refactor: use client metadata
This commit is contained in:
@ -57,22 +57,19 @@ def generate_supported_types():
|
||||
|
||||
def client_list_callback(scene, context):
|
||||
from . import operators
|
||||
from .bl_types.bl_user import BlUser
|
||||
|
||||
items = [(RP_COMMON, RP_COMMON, "")]
|
||||
|
||||
username = bpy.context.window_manager.session.username
|
||||
cli = operators.client
|
||||
if cli:
|
||||
client_keys = cli.list(filter=BlUser)
|
||||
for k in client_keys:
|
||||
name = cli.get(uuid=k).data["name"]
|
||||
|
||||
name_desc = name
|
||||
if name == username:
|
||||
client_ids = cli.online_users.keys()
|
||||
for id in client_ids:
|
||||
name_desc = id
|
||||
if id == username:
|
||||
name_desc += " (self)"
|
||||
|
||||
items.append((name, name_desc, ""))
|
||||
items.append((id, name_desc, ""))
|
||||
|
||||
return items
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
__all__ = [
|
||||
'bl_user',
|
||||
'bl_object',
|
||||
'bl_mesh',
|
||||
'bl_camera',
|
||||
|
@ -1,64 +0,0 @@
|
||||
import bpy
|
||||
import mathutils
|
||||
import jsondiff
|
||||
|
||||
from .. import utils
|
||||
from .. import presence
|
||||
from .bl_datablock import BlDatablock
|
||||
from ..libs.replication.replication.constants import UP
|
||||
|
||||
|
||||
class BlUser(BlDatablock):
|
||||
bl_id = "users"
|
||||
bl_class = presence.User
|
||||
bl_delay_refresh = .1
|
||||
bl_delay_apply = .1
|
||||
bl_automatic_push = True
|
||||
bl_icon = 'CON_ARMATURE'
|
||||
|
||||
def construct(self, data):
|
||||
user = bpy.data.window_managers['WinMan'].online_users.add()
|
||||
user.name = data['name']
|
||||
user.username = data['name']
|
||||
user.current_frame = data['current_frame']
|
||||
|
||||
def apply(self):
|
||||
if self.pointer is None:
|
||||
self.set_pointer()
|
||||
|
||||
self.load(self.data,self.pointer)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.hide_select and obj.uuid not in self.data['selected_objects']:
|
||||
obj.hide_select = False
|
||||
elif not obj.hide_select and obj.uuid in self.data['selected_objects']:
|
||||
obj.hide_select = True
|
||||
|
||||
presence.refresh_3d_view()
|
||||
|
||||
self.state = UP
|
||||
|
||||
def load(self, data, target):
|
||||
target.current_frame = data['current_frame']
|
||||
|
||||
def dump(self, pointer=None):
|
||||
data = utils.dump_anything.dump(pointer)
|
||||
data['location'] = pointer.location
|
||||
data['color'] = pointer.color
|
||||
data['selected_objects'] = pointer.selected_objects
|
||||
data['view_matrix'] = pointer.view_matrix
|
||||
data['current_frame'] = bpy.context.scene.frame_current
|
||||
|
||||
return data
|
||||
|
||||
def update(self):
|
||||
self.pointer.is_dirty = True
|
||||
|
||||
def resolve(self):
|
||||
self.pointer = bpy.data.window_managers['WinMan'].online_users.get(self.data['name'])
|
||||
|
||||
def is_valid(self):
|
||||
return True
|
||||
|
||||
|
||||
|
@ -3,10 +3,10 @@ import logging
|
||||
import bpy
|
||||
|
||||
from . import operators, presence, utils
|
||||
from .bl_types.bl_user import BlUser
|
||||
from .libs.replication.replication.constants import FETCHED, RP_COMMON
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
|
||||
class Delayable():
|
||||
@ -83,7 +83,6 @@ class DynamicRightSelectTimer(Timer):
|
||||
super().__init__(timout)
|
||||
self._last_selection = []
|
||||
self._user = None
|
||||
self._user_metadata = None
|
||||
self._right_strategy = RP_COMMON
|
||||
|
||||
def execute(self):
|
||||
@ -94,7 +93,6 @@ class DynamicRightSelectTimer(Timer):
|
||||
# Find user
|
||||
if self._user is None:
|
||||
self._user = session.online_users.get(settings.username)
|
||||
self._user_metadata = self._user.get('metadata')
|
||||
|
||||
if self._right_strategy is None:
|
||||
self._right_strategy = session.get_config()[
|
||||
@ -140,21 +138,25 @@ class DynamicRightSelectTimer(Timer):
|
||||
return
|
||||
|
||||
self._last_selection = current_selection
|
||||
self._user_metadata['selected_objects'] = current_selection
|
||||
|
||||
session.update_user_metadata(self._user_metadata)
|
||||
user_metadata = {
|
||||
'selected_objects': current_selection
|
||||
}
|
||||
|
||||
session.update_user_metadata(user_metadata)
|
||||
logger.info("Update selection")
|
||||
|
||||
# Fix deselection until right managment refactoring (with Roles concepts)
|
||||
if len(current_selection) == 0 and self._right_strategy == RP_COMMON:
|
||||
owned_keys = session.list(
|
||||
filter_owner=settings.username)
|
||||
for key in owned_keys:
|
||||
node = session.get(uuid=key)
|
||||
if not isinstance(node, BlUser):
|
||||
session.change_owner(
|
||||
key,
|
||||
RP_COMMON,
|
||||
recursive=recursive)
|
||||
|
||||
session.change_owner(
|
||||
key,
|
||||
RP_COMMON,
|
||||
recursive=recursive)
|
||||
|
||||
for user, user_info in session.online_users.items():
|
||||
if user != settings.username:
|
||||
@ -190,8 +192,9 @@ class Draw(Delayable):
|
||||
|
||||
class DrawClient(Draw):
|
||||
def execute(self):
|
||||
session = operators.client
|
||||
if session and presence.renderer:
|
||||
session = getattr(operators, 'client')
|
||||
renderer = getattr(presence, 'renderer')
|
||||
if session and renderer:
|
||||
settings = bpy.context.window_manager.session
|
||||
users = session.online_users
|
||||
|
||||
@ -199,10 +202,10 @@ class DrawClient(Draw):
|
||||
metadata = user.get('metadata')
|
||||
|
||||
if settings.presence_show_selected and 'selected_objects' in metadata.keys():
|
||||
presence.renderer.draw_client_selection(
|
||||
renderer.draw_client_selection(
|
||||
user['id'], metadata['color'], metadata['selected_objects'])
|
||||
if settings.presence_show_user and 'view_corners' in metadata:
|
||||
presence.renderer.draw_client_camera(
|
||||
renderer.draw_client_camera(
|
||||
user['id'], metadata['view_corners'], metadata['color'])
|
||||
|
||||
|
||||
@ -213,23 +216,31 @@ class ClientUpdate(Timer):
|
||||
def execute(self):
|
||||
settings = bpy.context.window_manager.session
|
||||
session_info = bpy.context.window_manager.session
|
||||
session = operators.client
|
||||
session = getattr(operators, 'client')
|
||||
if session:
|
||||
local_user = operators.client.online_users.get(
|
||||
session_info.username)
|
||||
if not local_user:
|
||||
return
|
||||
|
||||
metadata = {
|
||||
'view_corners': presence.get_view_corners(),
|
||||
'view_matrix': presence.get_view_matrix(),
|
||||
'color': (settings.client_color.r,
|
||||
settings.client_color.g,
|
||||
settings.client_color.b,
|
||||
1),
|
||||
}
|
||||
local_user_metadata = local_user.get('metadata')
|
||||
current_view_corners = presence.get_view_corners()
|
||||
|
||||
session.update_user_metadata(metadata)
|
||||
|
||||
logger.info("{}".format(local_user))
|
||||
if not local_user_metadata:
|
||||
logger.info("init user metadata")
|
||||
metadata = {
|
||||
'view_corners': current_view_corners,
|
||||
'view_matrix': presence.get_view_matrix(),
|
||||
'color': (settings.client_color.r,
|
||||
settings.client_color.g,
|
||||
settings.client_color.b,
|
||||
1),
|
||||
}
|
||||
session.update_user_metadata(metadata)
|
||||
elif current_view_corners != local_user_metadata['view_corners']:
|
||||
logger.info('update user metadata')
|
||||
local_user_metadata['view_corners'] = current_view_corners
|
||||
session.update_user_metadata(local_user_metadata)
|
||||
|
||||
# sync online users
|
||||
session_users = operators.client.online_users
|
||||
@ -240,7 +251,7 @@ class ClientUpdate(Timer):
|
||||
ui_users.remove(index)
|
||||
bpy.context.window_manager.session.presence_show_user = False
|
||||
bpy.context.window_manager.session.presence_show_user = True
|
||||
presence.refresh_3d_view()
|
||||
|
||||
break
|
||||
|
||||
for user in session_users:
|
||||
@ -248,3 +259,6 @@ class ClientUpdate(Timer):
|
||||
new_key = ui_users.add()
|
||||
new_key.name = user
|
||||
new_key.username = user
|
||||
|
||||
# TODO: event drivent 3d view refresh
|
||||
presence.refresh_3d_view()
|
||||
|
Submodule multi_user/libs/replication updated: 20c122a522...d8537c31c0
@ -36,7 +36,6 @@ modal_executor_queue = None
|
||||
|
||||
# OPERATORS
|
||||
|
||||
|
||||
class SessionStartOperator(bpy.types.Operator):
|
||||
bl_idname = "session.start"
|
||||
bl_label = "start"
|
||||
@ -54,16 +53,15 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
users = bpy.data.window_managers['WinMan'].online_users
|
||||
|
||||
# TODO: Sync server clients
|
||||
|
||||
users.clear()
|
||||
|
||||
|
||||
# save config
|
||||
settings.save(context)
|
||||
|
||||
bpy_factory = ReplicatedDataFactory()
|
||||
supported_bl_types = []
|
||||
ui_context = context.copy()
|
||||
|
||||
# init the factory with supported types
|
||||
for type in bl_types.types_to_register():
|
||||
type_module = getattr(bl_types, type)
|
||||
@ -87,6 +85,8 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
target_type=type_module_class))
|
||||
|
||||
client = Session(factory=bpy_factory)
|
||||
|
||||
|
||||
|
||||
if self.host:
|
||||
# Scene setup
|
||||
@ -118,18 +118,6 @@ class SessionStartOperator(bpy.types.Operator):
|
||||
"A session is already hosted on this address")
|
||||
return {"CANCELLED"}
|
||||
|
||||
# Init user settings
|
||||
usr = presence.User(
|
||||
username=settings.username,
|
||||
color=(settings.client_color.r,
|
||||
settings.client_color.g,
|
||||
settings.client_color.b,
|
||||
1),
|
||||
)
|
||||
|
||||
settings.user_uuid = client.add(usr, owner=settings.username)
|
||||
client.commit(settings.user_uuid)
|
||||
|
||||
if self.host:
|
||||
for scene in bpy.data.scenes:
|
||||
scene_uuid = client.add(scene)
|
||||
|
@ -122,33 +122,6 @@ def get_view_matrix():
|
||||
|
||||
return matrix_dumper.dump(rv3d.view_matrix)
|
||||
|
||||
class User():
|
||||
def __init__(self, username=None, color=(0, 0, 0, 1)):
|
||||
self.is_dirty = False
|
||||
self.name = username
|
||||
self.color = color
|
||||
self.location = [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
|
||||
self.selected_objects = []
|
||||
self.last_select_objects = []
|
||||
self.view_matrix = None
|
||||
|
||||
def update_location(self):
|
||||
current_coords = get_view_corners()
|
||||
area, region, rv3d = view3d_find()
|
||||
|
||||
if area and region and rv3d:
|
||||
current_coords = list(get_view_corners())
|
||||
if current_coords and self.location != current_coords:
|
||||
self.location = current_coords
|
||||
|
||||
matrix_dumper = utils.dump_anything.Dumper()
|
||||
current_vm = matrix_dumper.dump(rv3d.view_matrix)
|
||||
if self.view_matrix != current_vm:
|
||||
self.view_matrix = current_vm
|
||||
|
||||
def update_selected_objects(self, context):
|
||||
self.selected_objects = utils.get_selected_objects(context.scene)
|
||||
|
||||
def update_presence(self, context):
|
||||
global renderer
|
||||
|
||||
@ -226,14 +199,14 @@ class DrawFactory(object):
|
||||
|
||||
self.d2d_items.clear()
|
||||
|
||||
def draw_client_selection(self, client_uuid, client_color, client_selection):
|
||||
local_user = bpy.context.window_manager.session.user_uuid
|
||||
def draw_client_selection(self, client_id, client_color, client_selection):
|
||||
local_user = bpy.context.window_manager.session.username
|
||||
|
||||
if local_user != client_uuid:
|
||||
self.flush_selection(client_uuid)
|
||||
if local_user != client_id:
|
||||
self.flush_selection(client_id)
|
||||
|
||||
for select_ob in client_selection:
|
||||
drawable_key = "{}_select_{}".format(client_uuid, select_ob)
|
||||
drawable_key = "{}_select_{}".format(client_id, select_ob)
|
||||
|
||||
ob = utils.find_from_attr("uuid", select_ob, bpy.data.objects)
|
||||
if not ob:
|
||||
@ -282,11 +255,11 @@ class DrawFactory(object):
|
||||
|
||||
self.d3d_items[key] = (shader, batch, color)
|
||||
|
||||
def draw_client_camera(self, client_uuid, client_location, client_color):
|
||||
def draw_client_camera(self, client_id, client_location, client_color):
|
||||
if client_location:
|
||||
local_user = bpy.context.window_manager.session.user_uuid
|
||||
local_user = bpy.context.window_manager.session.username
|
||||
|
||||
if local_user != client_uuid:
|
||||
if local_user != client_id:
|
||||
try:
|
||||
indices = (
|
||||
(1, 3), (2, 1), (3, 0),
|
||||
@ -301,8 +274,8 @@ class DrawFactory(object):
|
||||
batch = batch_for_shader(
|
||||
shader, 'LINES', {"pos": position}, indices=indices)
|
||||
|
||||
self.d3d_items[client_uuid] = (shader, batch, color)
|
||||
self.d2d_items[client_uuid] = (position[1], client_uuid, color)
|
||||
self.d3d_items[client_id] = (shader, batch, color)
|
||||
self.d2d_items[client_id] = (position[1], client_id, color)
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Draw client exception {}".format(e))
|
||||
|
@ -1,7 +1,6 @@
|
||||
import bpy
|
||||
|
||||
from . import operators
|
||||
from .bl_types.bl_user import BlUser
|
||||
from .libs.replication.replication.constants import (ADDED, ERROR, FETCHED,
|
||||
MODIFIED, RP_COMMON, UP)
|
||||
|
||||
@ -188,7 +187,7 @@ class SESSION_PT_user(bpy.types.Panel):
|
||||
# Create a simple row.
|
||||
row = layout.row()
|
||||
box = row.box()
|
||||
split = box.split(factor=0.3)
|
||||
split = box.split(factor=0.5)
|
||||
split.label(text="user")
|
||||
split.label(text="frame")
|
||||
split.label(text="ping")
|
||||
@ -219,7 +218,7 @@ class SESSION_UL_users(bpy.types.UIList):
|
||||
ping = str(user_stat['latency'])
|
||||
break
|
||||
|
||||
split = layout.split(factor=0.3)
|
||||
split = layout.split(factor=0.5)
|
||||
split.label(text=item.username)
|
||||
split.label(text=str(item.current_frame))
|
||||
split.label(text=ping)
|
||||
@ -256,7 +255,7 @@ def draw_property(context, parent, property_uuid, level=0):
|
||||
settings = context.window_manager.session
|
||||
item = operators.client.get(uuid=property_uuid)
|
||||
|
||||
if item.str_type == 'BlUser' or item.state == ERROR:
|
||||
if item.state == ERROR:
|
||||
return
|
||||
|
||||
area_msg = parent.row(align=True)
|
||||
|
@ -27,6 +27,7 @@ def has_driver(target):
|
||||
and target.animation_data
|
||||
and target.animation_data.drivers)
|
||||
|
||||
|
||||
def find_from_attr(attr_name, attr_value, list):
|
||||
for item in list:
|
||||
if getattr(item, attr_name, None) == attr_value:
|
||||
@ -56,7 +57,7 @@ def get_datablock_users(datablock):
|
||||
def random_string_digits(stringLength=6):
|
||||
"""Generate a random string of letters and digits """
|
||||
lettersAndDigits = string.ascii_letters + string.digits
|
||||
return ''.join(random.choice(lettersAndDigits) for i in range(stringLength))
|
||||
return ''.join(random.choices(lettersAndDigits, k=stringLength))
|
||||
|
||||
|
||||
def clean_scene():
|
||||
@ -151,6 +152,7 @@ def dump_datablock_attibutes(datablock=None, attributes=[], depth=1, dickt=None)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def resolve_from_id(id, optionnal_type=None):
|
||||
for category in dir(bpy.data):
|
||||
root = getattr(bpy.data, category)
|
||||
|
Reference in New Issue
Block a user