feat: undo/redo handler

The solution for now is to resolve datablock references when undo appen.

Related to #32.
This commit is contained in:
Swann Martinez 2020-01-14 11:49:36 +01:00
parent f55319c453
commit 2eec228c3e
No known key found for this signature in database
GPG Key ID: 414CCAFD8DA720E1
3 changed files with 35 additions and 8 deletions

View File

@ -107,14 +107,20 @@ class BlDatablock(ReplicatedDatablock):
return [self.pointer.library] return [self.pointer.library]
def resolve(self): def resolve(self):
self.pointer = utils.find_from_attr('uuid', self.uuid, bpy.data.scenes) datablock_ref = None
datablock_root = getattr(bpy.data, self.bl_id)
datablock_ref = utils.find_from_attr('uuid', self.uuid, datablock_root)
if not self.pointer: # In case of lost uuid (ex: undo), resolve by name and reassign it
self.pointer = getattr(bpy.data,self.bl_id).get(self.data['name']) # TODO: avoid reference storing
print(self.data['name']) if not datablock_ref:
if self.pointer: datablock_ref = getattr(
setattr(self.pointer, 'uuid', self.uuid) bpy.data, self.bl_id).get(self.data['name'])
if datablock_ref:
setattr(datablock_ref, 'uuid', self.uuid)
self.pointer = datablock_ref
def dump(self, pointer=None): def dump(self, pointer=None):
data = {} data = {}

View File

@ -41,6 +41,9 @@ class BlUser(BlDatablock):
def update(self): def update(self):
self.pointer.is_dirty = True self.pointer.is_dirty = True
def resolve(self):
pass
def is_valid(self): def is_valid(self):
return True return True

View File

@ -41,7 +41,6 @@ class SessionStartOperator(bpy.types.Operator):
bl_idname = "session.start" bl_idname = "session.start"
bl_label = "start" bl_label = "start"
bl_description = "connect to a net server" bl_description = "connect to a net server"
bl_options = {"REGISTER"}
host: bpy.props.BoolProperty(default=False) host: bpy.props.BoolProperty(default=False)
@ -382,6 +381,7 @@ classes = (
SessionCommit, SessionCommit,
ApplyArmatureOperator, ApplyArmatureOperator,
) )
@persistent @persistent
def load_pre_handler(dummy): def load_pre_handler(dummy):
global client global client
@ -389,6 +389,19 @@ def load_pre_handler(dummy):
if client and client.state in [STATE_ACTIVE, STATE_SYNCING]: if client and client.state in [STATE_ACTIVE, STATE_SYNCING]:
bpy.ops.session.stop() bpy.ops.session.stop()
@persistent
def sanitize_deps_graph(dummy):
"""sanitize deps graph
Temporary solution to resolve each node pointers after a Undo.
A future solution should be to avoid storing dataclock reference...
"""
global client
if client and client.state in [STATE_ACTIVE]:
for node_key in client.list():
client.get(node_key).resolve()
def register(): def register():
from bpy.utils import register_class from bpy.utils import register_class
@ -397,6 +410,9 @@ def register():
bpy.app.handlers.load_pre.append(load_pre_handler) bpy.app.handlers.load_pre.append(load_pre_handler)
bpy.app.handlers.undo_post.append(sanitize_deps_graph)
bpy.app.handlers.redo_post.append(sanitize_deps_graph)
def unregister(): def unregister():
global client global client
@ -410,6 +426,8 @@ def unregister():
bpy.app.handlers.load_pre.remove(load_pre_handler) bpy.app.handlers.load_pre.remove(load_pre_handler)
bpy.app.handlers.undo_post.remove(sanitize_deps_graph)
bpy.app.handlers.redo_post.remove(sanitize_deps_graph)
if __name__ == "__main__": if __name__ == "__main__":
register() register()