Merge branch '152-generated-images-are-not-synced' into 'develop'
Resolve "Generated images are not synced" See merge request slumber/multi-user!83
This commit is contained in:
@ -44,7 +44,7 @@ from . import environment
|
|||||||
|
|
||||||
|
|
||||||
DEPENDENCIES = {
|
DEPENDENCIES = {
|
||||||
("replication", '0.1.16'),
|
("replication", '0.1.17'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,6 +137,7 @@ class BlAction(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'ACTION_TWEAK'
|
bl_icon = 'ACTION_TWEAK'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.actions.new(data["name"])
|
return bpy.data.actions.new(data["name"])
|
||||||
|
@ -33,6 +33,7 @@ class BlArmature(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'ARMATURE_DATA'
|
bl_icon = 'ARMATURE_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.armatures.new(data["name"])
|
return bpy.data.armatures.new(data["name"])
|
||||||
|
@ -31,6 +31,7 @@ class BlCamera(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'CAMERA_DATA'
|
bl_icon = 'CAMERA_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.cameras.new(data["name"])
|
return bpy.data.cameras.new(data["name"])
|
||||||
|
@ -89,6 +89,7 @@ class BlCollection(BlDatablock):
|
|||||||
bl_delay_apply = 1
|
bl_delay_apply = 1
|
||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = True
|
bl_check_common = True
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
if self.is_library:
|
if self.is_library:
|
||||||
|
@ -146,6 +146,7 @@ class BlCurve(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'CURVE_DATA'
|
bl_icon = 'CURVE_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.curves.new(data["name"], data["type"])
|
return bpy.data.curves.new(data["name"], data["type"])
|
||||||
|
@ -111,8 +111,10 @@ class BlDatablock(ReplicatedDatablock):
|
|||||||
bl_automatic_push : boolean
|
bl_automatic_push : boolean
|
||||||
bl_icon : type icon (blender icon name)
|
bl_icon : type icon (blender icon name)
|
||||||
bl_check_common: enable check even in common rights
|
bl_check_common: enable check even in common rights
|
||||||
|
bl_reload_parent: reload parent
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
instance = kwargs.get('instance', None)
|
instance = kwargs.get('instance', None)
|
||||||
|
@ -54,11 +54,12 @@ class BlFile(ReplicatedDatablock):
|
|||||||
bl_id = 'file'
|
bl_id = 'file'
|
||||||
bl_name = "file"
|
bl_name = "file"
|
||||||
bl_class = Path
|
bl_class = Path
|
||||||
bl_delay_refresh = 0
|
bl_delay_refresh = 2
|
||||||
bl_delay_apply = 1
|
bl_delay_apply = 1
|
||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'FILE'
|
bl_icon = 'FILE'
|
||||||
|
bl_reload_parent = True
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -118,11 +119,7 @@ class BlFile(ReplicatedDatablock):
|
|||||||
"""
|
"""
|
||||||
Writing the file
|
Writing the file
|
||||||
"""
|
"""
|
||||||
# TODO: check for empty data
|
|
||||||
|
|
||||||
if target.exists() and not self.diff():
|
|
||||||
logging.info(f"{data['name']} already on the disk, skipping.")
|
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
file = open(target, "wb")
|
file = open(target, "wb")
|
||||||
file.write(data['file'])
|
file.write(data['file'])
|
||||||
@ -140,4 +137,4 @@ class BlFile(ReplicatedDatablock):
|
|||||||
else:
|
else:
|
||||||
memory_size = sys.getsizeof(self.data['file'])-33
|
memory_size = sys.getsizeof(self.data['file'])-33
|
||||||
disk_size = self.instance.stat().st_size
|
disk_size = self.instance.stat().st_size
|
||||||
return memory_size == disk_size
|
return memory_size != disk_size
|
||||||
|
@ -35,6 +35,7 @@ class BlFont(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'FILE_FONT'
|
bl_icon = 'FILE_FONT'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
filename = data.get('filename')
|
filename = data.get('filename')
|
||||||
|
@ -235,6 +235,7 @@ class BlGpencil(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'GREASEPENCIL'
|
bl_icon = 'GREASEPENCIL'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.grease_pencils.new(data["name"])
|
return bpy.data.grease_pencils.new(data["name"])
|
||||||
|
@ -51,11 +51,12 @@ format_to_ext = {
|
|||||||
class BlImage(BlDatablock):
|
class BlImage(BlDatablock):
|
||||||
bl_id = "images"
|
bl_id = "images"
|
||||||
bl_class = bpy.types.Image
|
bl_class = bpy.types.Image
|
||||||
bl_delay_refresh = 1
|
bl_delay_refresh = 2
|
||||||
bl_delay_apply = 1
|
bl_delay_apply = 1
|
||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'IMAGE_DATA'
|
bl_icon = 'IMAGE_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.images.new(
|
return bpy.data.images.new(
|
||||||
@ -72,7 +73,6 @@ class BlImage(BlDatablock):
|
|||||||
target.filepath_raw = get_filepath(data['filename'])
|
target.filepath_raw = get_filepath(data['filename'])
|
||||||
target.colorspace_settings.name = data["colorspace_settings"]["name"]
|
target.colorspace_settings.name = data["colorspace_settings"]["name"]
|
||||||
|
|
||||||
|
|
||||||
def _dump(self, instance=None):
|
def _dump(self, instance=None):
|
||||||
assert(instance)
|
assert(instance)
|
||||||
|
|
||||||
@ -96,6 +96,9 @@ class BlImage(BlDatablock):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def diff(self):
|
def diff(self):
|
||||||
|
if self.instance.is_dirty:
|
||||||
|
self.instance.save()
|
||||||
|
|
||||||
if self.instance and (self.instance.name != self.data['name']):
|
if self.instance and (self.instance.name != self.data['name']):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@ -103,7 +106,6 @@ class BlImage(BlDatablock):
|
|||||||
|
|
||||||
def _resolve_deps_implementation(self):
|
def _resolve_deps_implementation(self):
|
||||||
deps = []
|
deps = []
|
||||||
if self.instance.filepath:
|
|
||||||
|
|
||||||
if self.instance.packed_file:
|
if self.instance.packed_file:
|
||||||
filename = Path(bpy.path.abspath(self.instance.filepath)).name
|
filename = Path(bpy.path.abspath(self.instance.filepath)).name
|
||||||
@ -118,6 +120,7 @@ class BlImage(BlDatablock):
|
|||||||
self.instance.filepath = get_filepath(filename)
|
self.instance.filepath = get_filepath(filename)
|
||||||
self.instance.save()
|
self.instance.save()
|
||||||
|
|
||||||
|
if self.instance.filepath:
|
||||||
deps.append(Path(bpy.path.abspath(self.instance.filepath)))
|
deps.append(Path(bpy.path.abspath(self.instance.filepath)))
|
||||||
|
|
||||||
return deps
|
return deps
|
||||||
|
@ -34,6 +34,7 @@ class BlLattice(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'LATTICE_DATA'
|
bl_icon = 'LATTICE_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.lattices.new(data["name"])
|
return bpy.data.lattices.new(data["name"])
|
||||||
|
@ -31,6 +31,7 @@ class BlLibrary(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'LIBRARY_DATA_DIRECT'
|
bl_icon = 'LIBRARY_DATA_DIRECT'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
with bpy.data.libraries.load(filepath=data["filepath"], link=True) as (sourceData, targetData):
|
with bpy.data.libraries.load(filepath=data["filepath"], link=True) as (sourceData, targetData):
|
||||||
|
@ -31,6 +31,7 @@ class BlLight(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'LIGHT_DATA'
|
bl_icon = 'LIGHT_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.lights.new(data["name"], data["type"])
|
return bpy.data.lights.new(data["name"], data["type"])
|
||||||
|
@ -32,6 +32,7 @@ class BlLightprobe(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'LIGHTPROBE_GRID'
|
bl_icon = 'LIGHTPROBE_GRID'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
type = 'CUBE' if data['type'] == 'CUBEMAP' else data['type']
|
type = 'CUBE' if data['type'] == 'CUBEMAP' else data['type']
|
||||||
|
@ -327,6 +327,7 @@ class BlMaterial(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'MATERIAL_DATA'
|
bl_icon = 'MATERIAL_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.materials.new(data["name"])
|
return bpy.data.materials.new(data["name"])
|
||||||
|
@ -54,6 +54,7 @@ class BlMesh(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'MESH_DATA'
|
bl_icon = 'MESH_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
instance = bpy.data.meshes.new(data["name"])
|
instance = bpy.data.meshes.new(data["name"])
|
||||||
|
@ -70,6 +70,7 @@ class BlMetaball(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'META_BALL'
|
bl_icon = 'META_BALL'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.metaballs.new(data["name"])
|
return bpy.data.metaballs.new(data["name"])
|
||||||
|
@ -33,6 +33,7 @@ class BlNodeGroup(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'NODETREE'
|
bl_icon = 'NODETREE'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.node_groups.new(data["name"], data["type"])
|
return bpy.data.node_groups.new(data["name"], data["type"])
|
||||||
|
@ -102,6 +102,7 @@ class BlObject(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'OBJECT_DATA'
|
bl_icon = 'OBJECT_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
instance = None
|
instance = None
|
||||||
|
@ -278,6 +278,7 @@ class BlScene(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = True
|
bl_check_common = True
|
||||||
bl_icon = 'SCENE_DATA'
|
bl_icon = 'SCENE_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -130,6 +130,7 @@ class BlSequencer(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = True
|
bl_check_common = True
|
||||||
bl_icon = 'SEQUENCE'
|
bl_icon = 'SEQUENCE'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
# Get the scene
|
# Get the scene
|
||||||
|
@ -35,6 +35,7 @@ class BlSound(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'SOUND'
|
bl_icon = 'SOUND'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
filename = data.get('filename')
|
filename = data.get('filename')
|
||||||
|
@ -31,6 +31,7 @@ class BlSpeaker(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'SPEAKER'
|
bl_icon = 'SPEAKER'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _load_implementation(self, data, target):
|
def _load_implementation(self, data, target):
|
||||||
loader = Loader()
|
loader = Loader()
|
||||||
|
@ -31,6 +31,7 @@ class BlTexture(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'TEXTURE'
|
bl_icon = 'TEXTURE'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _load_implementation(self, data, target):
|
def _load_implementation(self, data, target):
|
||||||
loader = Loader()
|
loader = Loader()
|
||||||
|
@ -32,6 +32,7 @@ class BlVolume(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = False
|
bl_check_common = False
|
||||||
bl_icon = 'VOLUME_DATA'
|
bl_icon = 'VOLUME_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _load_implementation(self, data, target):
|
def _load_implementation(self, data, target):
|
||||||
loader = Loader()
|
loader = Loader()
|
||||||
|
@ -34,6 +34,7 @@ class BlWorld(BlDatablock):
|
|||||||
bl_automatic_push = True
|
bl_automatic_push = True
|
||||||
bl_check_common = True
|
bl_check_common = True
|
||||||
bl_icon = 'WORLD_DATA'
|
bl_icon = 'WORLD_DATA'
|
||||||
|
bl_reload_parent = False
|
||||||
|
|
||||||
def _construct(self, data):
|
def _construct(self, data):
|
||||||
return bpy.data.worlds.new(data["name"])
|
return bpy.data.worlds.new(data["name"])
|
||||||
|
@ -28,6 +28,7 @@ from .presence import (renderer,
|
|||||||
generate_user_camera,
|
generate_user_camera,
|
||||||
get_view_matrix,
|
get_view_matrix,
|
||||||
refresh_sidebar_view)
|
refresh_sidebar_view)
|
||||||
|
from . import operators
|
||||||
from replication.constants import (FETCHED,
|
from replication.constants import (FETCHED,
|
||||||
UP,
|
UP,
|
||||||
RP_COMMON,
|
RP_COMMON,
|
||||||
@ -41,7 +42,8 @@ from replication.constants import (FETCHED,
|
|||||||
from replication.interface import session
|
from replication.interface import session
|
||||||
from replication.exception import NonAuthorizedOperationError
|
from replication.exception import NonAuthorizedOperationError
|
||||||
|
|
||||||
def is_annotating(context:bpy.types.Context):
|
|
||||||
|
def is_annotating(context: bpy.types.Context):
|
||||||
""" Check if the annotate mode is enabled
|
""" Check if the annotate mode is enabled
|
||||||
"""
|
"""
|
||||||
return bpy.context.workspace.tools.from_space_view3d_mode('OBJECT', create=False).idname == 'builtin.annotate'
|
return bpy.context.workspace.tools.from_space_view3d_mode('OBJECT', create=False).idname == 'builtin.annotate'
|
||||||
@ -50,9 +52,6 @@ class Delayable():
|
|||||||
"""Delayable task interface
|
"""Delayable task interface
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.is_registered = False
|
|
||||||
|
|
||||||
def register(self):
|
def register(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -72,24 +71,29 @@ class Timer(Delayable):
|
|||||||
def __init__(self, duration=1):
|
def __init__(self, duration=1):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._timeout = duration
|
self._timeout = duration
|
||||||
self._running = True
|
self.is_running = False
|
||||||
|
|
||||||
def register(self):
|
def register(self):
|
||||||
"""Register the timer into the blender timer system
|
"""Register the timer into the blender timer system
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self.is_registered:
|
if not self.is_running:
|
||||||
bpy.app.timers.register(self.main)
|
bpy.app.timers.register(self.main)
|
||||||
self.is_registered = True
|
self.is_running = True
|
||||||
logging.debug(f"Register {self.__class__.__name__}")
|
logging.debug(f"Register {self.__class__.__name__}")
|
||||||
else:
|
else:
|
||||||
logging.debug(
|
logging.debug(
|
||||||
f"Timer {self.__class__.__name__} already registered")
|
f"Timer {self.__class__.__name__} already registered")
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
|
try:
|
||||||
self.execute()
|
self.execute()
|
||||||
|
except Exception as e:
|
||||||
if self._running:
|
logging.error(e)
|
||||||
|
self.unregister()
|
||||||
|
session.disconnect()
|
||||||
|
else:
|
||||||
|
if self.is_running:
|
||||||
return self._timeout
|
return self._timeout
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
@ -103,7 +107,7 @@ class Timer(Delayable):
|
|||||||
if bpy.app.timers.is_registered(self.main):
|
if bpy.app.timers.is_registered(self.main):
|
||||||
bpy.app.timers.unregister(self.main)
|
bpy.app.timers.unregister(self.main)
|
||||||
|
|
||||||
self._running = False
|
self.is_running = False
|
||||||
|
|
||||||
|
|
||||||
class ApplyTimer(Timer):
|
class ApplyTimer(Timer):
|
||||||
@ -126,14 +130,20 @@ class ApplyTimer(Timer):
|
|||||||
session.apply(node)
|
session.apply(node)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Fail to apply {node_ref.uuid}: {e}")
|
logging.error(f"Fail to apply {node_ref.uuid}: {e}")
|
||||||
|
else:
|
||||||
|
if self._type.bl_reload_parent:
|
||||||
|
parents = []
|
||||||
|
|
||||||
|
for n in session.list():
|
||||||
|
deps = session.get(uuid=n).dependencies
|
||||||
|
if deps and node in deps:
|
||||||
|
session.apply(n, force=True)
|
||||||
|
|
||||||
class DynamicRightSelectTimer(Timer):
|
class DynamicRightSelectTimer(Timer):
|
||||||
def __init__(self, timout=.1):
|
def __init__(self, timout=.1):
|
||||||
super().__init__(timout)
|
super().__init__(timout)
|
||||||
self._last_selection = []
|
self._last_selection = []
|
||||||
self._user = None
|
self._user = None
|
||||||
self._right_strategy = RP_COMMON
|
|
||||||
self._annotating = False
|
self._annotating = False
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
@ -155,7 +165,8 @@ class DynamicRightSelectTimer(Timer):
|
|||||||
# try to get the right on it
|
# try to get the right on it
|
||||||
if registered_gp.owner == RP_COMMON:
|
if registered_gp.owner == RP_COMMON:
|
||||||
self._annotating = True
|
self._annotating = True
|
||||||
logging.debug("Getting the right on the annotation GP")
|
logging.debug(
|
||||||
|
"Getting the right on the annotation GP")
|
||||||
session.change_owner(
|
session.change_owner(
|
||||||
registered_gp.uuid,
|
registered_gp.uuid,
|
||||||
settings.username,
|
settings.username,
|
||||||
@ -193,7 +204,8 @@ class DynamicRightSelectTimer(Timer):
|
|||||||
ignore_warnings=True,
|
ignore_warnings=True,
|
||||||
affect_dependencies=recursive)
|
affect_dependencies=recursive)
|
||||||
except NonAuthorizedOperationError:
|
except NonAuthorizedOperationError:
|
||||||
logging.warning(f"Not authorized to change {node} owner")
|
logging.warning(
|
||||||
|
f"Not authorized to change {node} owner")
|
||||||
|
|
||||||
# change new selection to our
|
# change new selection to our
|
||||||
for obj in obj_ours:
|
for obj in obj_ours:
|
||||||
@ -211,7 +223,8 @@ class DynamicRightSelectTimer(Timer):
|
|||||||
ignore_warnings=True,
|
ignore_warnings=True,
|
||||||
affect_dependencies=recursive)
|
affect_dependencies=recursive)
|
||||||
except NonAuthorizedOperationError:
|
except NonAuthorizedOperationError:
|
||||||
logging.warning(f"Not authorized to change {node} owner")
|
logging.warning(
|
||||||
|
f"Not authorized to change {node} owner")
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -225,7 +238,7 @@ class DynamicRightSelectTimer(Timer):
|
|||||||
logging.debug("Update selection")
|
logging.debug("Update selection")
|
||||||
|
|
||||||
# Fix deselection until right managment refactoring (with Roles concepts)
|
# Fix deselection until right managment refactoring (with Roles concepts)
|
||||||
if len(current_selection) == 0 and self._right_strategy == RP_COMMON:
|
if len(current_selection) == 0 :
|
||||||
owned_keys = session.list(
|
owned_keys = session.list(
|
||||||
filter_owner=settings.username)
|
filter_owner=settings.username)
|
||||||
for key in owned_keys:
|
for key in owned_keys:
|
||||||
@ -237,7 +250,8 @@ class DynamicRightSelectTimer(Timer):
|
|||||||
ignore_warnings=True,
|
ignore_warnings=True,
|
||||||
affect_dependencies=recursive)
|
affect_dependencies=recursive)
|
||||||
except NonAuthorizedOperationError:
|
except NonAuthorizedOperationError:
|
||||||
logging.warning(f"Not authorized to change {key} owner")
|
logging.warning(
|
||||||
|
f"Not authorized to change {key} owner")
|
||||||
|
|
||||||
for obj in bpy.data.objects:
|
for obj in bpy.data.objects:
|
||||||
object_uuid = getattr(obj, 'uuid', None)
|
object_uuid = getattr(obj, 'uuid', None)
|
||||||
@ -246,6 +260,7 @@ class DynamicRightSelectTimer(Timer):
|
|||||||
if obj.hide_select != is_selectable:
|
if obj.hide_select != is_selectable:
|
||||||
obj.hide_select = is_selectable
|
obj.hide_select = is_selectable
|
||||||
|
|
||||||
|
|
||||||
class ClientUpdate(Timer):
|
class ClientUpdate(Timer):
|
||||||
def __init__(self, timout=.1):
|
def __init__(self, timout=.1):
|
||||||
super().__init__(timout)
|
super().__init__(timout)
|
||||||
|
@ -42,7 +42,7 @@ from . import bl_types, delayable, environment, ui, utils
|
|||||||
from .presence import SessionStatusWidget, renderer, view3d_find
|
from .presence import SessionStatusWidget, renderer, view3d_find
|
||||||
|
|
||||||
background_execution_queue = Queue()
|
background_execution_queue = Queue()
|
||||||
delayables = []
|
deleyables = []
|
||||||
stop_modal_executor = False
|
stop_modal_executor = False
|
||||||
|
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ def initialize_session():
|
|||||||
node_ref.apply()
|
node_ref.apply()
|
||||||
|
|
||||||
# Step 4: Register blender timers
|
# Step 4: Register blender timers
|
||||||
for d in delayables:
|
for d in deleyables:
|
||||||
d.register()
|
d.register()
|
||||||
|
|
||||||
if settings.update_method == 'DEPSGRAPH':
|
if settings.update_method == 'DEPSGRAPH':
|
||||||
@ -93,15 +93,16 @@ def initialize_session():
|
|||||||
def on_connection_end(reason="none"):
|
def on_connection_end(reason="none"):
|
||||||
"""Session connection finished handler
|
"""Session connection finished handler
|
||||||
"""
|
"""
|
||||||
global delayables, stop_modal_executor
|
global deleyables, stop_modal_executor
|
||||||
settings = utils.get_preferences()
|
settings = utils.get_preferences()
|
||||||
|
|
||||||
# Step 1: Unregister blender timers
|
# Step 1: Unregister blender timers
|
||||||
for d in delayables:
|
for d in deleyables:
|
||||||
try:
|
try:
|
||||||
d.unregister()
|
d.unregister()
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
deleyables.clear()
|
||||||
|
|
||||||
stop_modal_executor = True
|
stop_modal_executor = True
|
||||||
|
|
||||||
@ -131,7 +132,7 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
global delayables
|
global deleyables
|
||||||
|
|
||||||
settings = utils.get_preferences()
|
settings = utils.get_preferences()
|
||||||
runtime_settings = context.window_manager.session
|
runtime_settings = context.window_manager.session
|
||||||
@ -139,7 +140,7 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
admin_pass = runtime_settings.password
|
admin_pass = runtime_settings.password
|
||||||
use_extern_update = settings.update_method == 'DEPSGRAPH'
|
use_extern_update = settings.update_method == 'DEPSGRAPH'
|
||||||
users.clear()
|
users.clear()
|
||||||
delayables.clear()
|
deleyables.clear()
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
if len(logger.handlers) == 1:
|
if len(logger.handlers) == 1:
|
||||||
@ -191,7 +192,7 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
|
|
||||||
if settings.update_method == 'DEFAULT':
|
if settings.update_method == 'DEFAULT':
|
||||||
if type_local_config.bl_delay_apply > 0:
|
if type_local_config.bl_delay_apply > 0:
|
||||||
delayables.append(
|
deleyables.append(
|
||||||
delayable.ApplyTimer(
|
delayable.ApplyTimer(
|
||||||
timout=type_local_config.bl_delay_apply,
|
timout=type_local_config.bl_delay_apply,
|
||||||
target_type=type_module_class))
|
target_type=type_module_class))
|
||||||
@ -207,7 +208,7 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
external_update_handling=use_extern_update)
|
external_update_handling=use_extern_update)
|
||||||
|
|
||||||
if settings.update_method == 'DEPSGRAPH':
|
if settings.update_method == 'DEPSGRAPH':
|
||||||
delayables.append(delayable.ApplyTimer(
|
deleyables.append(delayable.ApplyTimer(
|
||||||
settings.depsgraph_update_rate/1000))
|
settings.depsgraph_update_rate/1000))
|
||||||
|
|
||||||
# Host a session
|
# Host a session
|
||||||
@ -258,8 +259,8 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
logging.error(str(e))
|
logging.error(str(e))
|
||||||
|
|
||||||
# Background client updates service
|
# Background client updates service
|
||||||
delayables.append(delayable.ClientUpdate())
|
deleyables.append(delayable.ClientUpdate())
|
||||||
delayables.append(delayable.DynamicRightSelectTimer())
|
deleyables.append(delayable.DynamicRightSelectTimer())
|
||||||
|
|
||||||
session_update = delayable.SessionStatusUpdate()
|
session_update = delayable.SessionStatusUpdate()
|
||||||
session_user_sync = delayable.SessionUserSync()
|
session_user_sync = delayable.SessionUserSync()
|
||||||
@ -270,9 +271,9 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
session_user_sync.register()
|
session_user_sync.register()
|
||||||
session_background_executor.register()
|
session_background_executor.register()
|
||||||
|
|
||||||
delayables.append(session_background_executor)
|
deleyables.append(session_background_executor)
|
||||||
delayables.append(session_update)
|
deleyables.append(session_update)
|
||||||
delayables.append(session_user_sync)
|
deleyables.append(session_user_sync)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -332,7 +333,7 @@ class SessionStopOperator(bpy.types.Operator):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
global delayables, stop_modal_executor
|
global deleyables, stop_modal_executor
|
||||||
|
|
||||||
if session:
|
if session:
|
||||||
try:
|
try:
|
||||||
@ -359,7 +360,7 @@ class SessionKickOperator(bpy.types.Operator):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
global delayables, stop_modal_executor
|
global deleyables, stop_modal_executor
|
||||||
assert(session)
|
assert(session)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
Reference in New Issue
Block a user