feat: append dump function to save the db
This commit is contained in:
parent
eccc681f7b
commit
021e132fb3
@ -28,14 +28,15 @@ def module_can_be_imported(name):
|
||||
|
||||
# UTILITY FUNCTIONS
|
||||
def client_list_callback(scene, context):
|
||||
from . import operators
|
||||
from . import client
|
||||
|
||||
items = [("Common", "Common", "")]
|
||||
|
||||
username = bpy.context.window_manager.session.username
|
||||
|
||||
if operators.client_keys:
|
||||
for k in operators.client_keys:
|
||||
if client.instance:
|
||||
client_keys = client.instance.list()
|
||||
for k in client_keys:
|
||||
if 'Client' in k[0]:
|
||||
name = k[1]
|
||||
|
||||
|
@ -10,6 +10,7 @@ import time
|
||||
from enum import Enum
|
||||
from random import randint
|
||||
import zmq
|
||||
import json
|
||||
|
||||
from . import helpers, message
|
||||
from .libs import dump_anything, umsgpack
|
||||
@ -204,6 +205,12 @@ class Client(object):
|
||||
# else:
|
||||
# return None
|
||||
|
||||
# SAVING FUNCTIONS
|
||||
def dump(self, filepath):
|
||||
with open('result.json',"w") as fp:
|
||||
for key, value in self.store.items():
|
||||
line = json.dumps(value.body)
|
||||
fp.write(line)
|
||||
|
||||
class Server(object):
|
||||
address = None # Server address
|
||||
|
@ -220,7 +220,6 @@ def load_mesh(target=None, data=None, create=False):
|
||||
|
||||
material_to_load = []
|
||||
material_to_load = revers(data["materials"])
|
||||
|
||||
target.materials.clear()
|
||||
# SLots
|
||||
i = 0
|
||||
@ -265,11 +264,11 @@ def load_object(target=None, data=None, create=False):
|
||||
|
||||
client = bpy.context.window_manager.session.username
|
||||
|
||||
if target.id == client:
|
||||
if target.id == client or target.id == "Common":
|
||||
target.hide_select = False
|
||||
else:
|
||||
target.hide_select = True
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Object {} loading error: {} ".format(data["name"], e))
|
||||
|
||||
@ -342,7 +341,7 @@ def load_collection(target=None, data=None, create=False):
|
||||
|
||||
client = bpy.context.window_manager.session.username
|
||||
|
||||
if target.id == client:
|
||||
if target.id == client or target.id == "Common":
|
||||
target.hide_select = False
|
||||
else:
|
||||
target.hide_select = True
|
||||
|
84
operators.py
84
operators.py
@ -10,6 +10,7 @@ from operator import itemgetter
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy_extras.io_utils import ExportHelper
|
||||
import mathutils
|
||||
from pathlib import Path
|
||||
|
||||
@ -26,23 +27,26 @@ execution_queue = queue.Queue()
|
||||
|
||||
# This function can savely be called in another thread.
|
||||
# The function will be executed when the timer runs the next time.
|
||||
def run_in_main_thread(function,args):
|
||||
|
||||
|
||||
def run_in_main_thread(function, args):
|
||||
execution_queue.put(function)
|
||||
|
||||
|
||||
def execute_queued_functions():
|
||||
while not execution_queue.empty():
|
||||
function, args = execution_queue.get()
|
||||
logger.info(args[0])
|
||||
function(args[0],args[1])
|
||||
function(args[0], args[1])
|
||||
return .1
|
||||
|
||||
|
||||
def clean_scene(elements=helpers.BPY_TYPES.keys()):
|
||||
for datablock in elements:
|
||||
datablock_ref =getattr(bpy.data, helpers.BPY_TYPES[datablock])
|
||||
datablock_ref = getattr(bpy.data, helpers.BPY_TYPES[datablock])
|
||||
for item in datablock_ref:
|
||||
try:
|
||||
datablock_ref.remove(item)
|
||||
#Catch last scene remove
|
||||
# Catch last scene remove
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
@ -53,7 +57,6 @@ def upload_client_instance_position():
|
||||
|
||||
key = "Client/{}".format(username)
|
||||
|
||||
|
||||
current_coords = draw.get_client_view_rect()
|
||||
client_list = client.instance.get(key)
|
||||
|
||||
@ -61,7 +64,7 @@ def upload_client_instance_position():
|
||||
if current_coords != client_list[0][1]['location']:
|
||||
client_list[0][1]['location'] = current_coords
|
||||
client.instance.set(key, client_list[0][1])
|
||||
|
||||
|
||||
|
||||
def update_client_selected_object(context):
|
||||
session = bpy.context.window_manager.session
|
||||
@ -70,7 +73,7 @@ def update_client_selected_object(context):
|
||||
client_data = client.instance.get(client_key)
|
||||
|
||||
selected_objects = helpers.get_selected_objects(context.scene)
|
||||
if len(selected_objects) > 0:
|
||||
if len(selected_objects) > 0 and len(client_data) > 0:
|
||||
|
||||
for obj in selected_objects:
|
||||
# if obj not in client_data[0][1]['active_objects']:
|
||||
@ -83,7 +86,9 @@ def update_client_selected_object(context):
|
||||
client_data[0][1]['active_objects'] = []
|
||||
client.instance.set(client_key, client_data[0][1])
|
||||
|
||||
#TODO: cleanup
|
||||
# TODO: cleanup
|
||||
|
||||
|
||||
def init_datablocks():
|
||||
for datatype in helpers.BPY_TYPES.keys():
|
||||
for item in getattr(bpy.data, helpers.BPY_TYPES[datatype]):
|
||||
@ -92,10 +97,10 @@ def init_datablocks():
|
||||
client.instance.set(key)
|
||||
|
||||
|
||||
def default_tick():
|
||||
def default_tick():
|
||||
upload_client_instance_position()
|
||||
|
||||
return .2
|
||||
|
||||
return .1
|
||||
|
||||
|
||||
def register_ticks():
|
||||
@ -103,6 +108,7 @@ def register_ticks():
|
||||
bpy.app.timers.register(default_tick)
|
||||
bpy.app.timers.register(execute_queued_functions)
|
||||
|
||||
|
||||
def unregister_ticks():
|
||||
# REGISTER Updaters
|
||||
try:
|
||||
@ -110,8 +116,10 @@ def unregister_ticks():
|
||||
bpy.app.timers.unregister(execute_queued_functions)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# OPERATORS
|
||||
|
||||
|
||||
class SessionJoinOperator(bpy.types.Operator):
|
||||
bl_idname = "session.join"
|
||||
bl_label = "join"
|
||||
@ -229,13 +237,14 @@ class SessionHostOperator(bpy.types.Operator):
|
||||
|
||||
net_settings = context.window_manager.session
|
||||
|
||||
script_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),"server.py")
|
||||
script_dir = os.path.join(os.path.dirname(
|
||||
os.path.abspath(__file__)), "server.py")
|
||||
|
||||
python_path = Path(bpy.app.binary_path_python)
|
||||
cwd_for_subprocesses = python_path.parent
|
||||
|
||||
server = subprocess.Popen(
|
||||
[str(python_path),script_dir],shell=False, stdout=subprocess.PIPE)
|
||||
[str(python_path), script_dir], shell=False, stdout=subprocess.PIPE)
|
||||
|
||||
bpy.ops.session.join()
|
||||
|
||||
@ -277,7 +286,6 @@ class SessionStopOperator(bpy.types.Operator):
|
||||
# client_instance = None
|
||||
net_settings.is_admin = False
|
||||
|
||||
|
||||
unregister_ticks()
|
||||
draw.renderer.stop()
|
||||
else:
|
||||
@ -319,9 +327,11 @@ class SessionPropertyRightOperator(bpy.types.Operator):
|
||||
val[0][1]['id'] = net_settings.clients
|
||||
|
||||
client.instance.set(key=self.key, value=val[0][1], override=True)
|
||||
|
||||
print("Updating {} rights to {}".format(
|
||||
self.key, net_settings.clients))
|
||||
item = helpers.resolve_bpy_path(self.key)
|
||||
if item:
|
||||
item.id = net_settings.clients
|
||||
logger.info("Updating {} rights to {}".format(
|
||||
self.key, net_settings.clients))
|
||||
else:
|
||||
print("Not admin")
|
||||
|
||||
@ -343,7 +353,8 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
||||
def execute(self, context):
|
||||
area, region, rv3d = draw.view3d_find()
|
||||
|
||||
target_client = client.instance.get("Client/{}".format(self.target_client))
|
||||
target_client = client.instance.get(
|
||||
"Client/{}".format(self.target_client))
|
||||
if target_client:
|
||||
rv3d.view_location = target_client[0][1]['location'][0]
|
||||
rv3d.view_distance = 30.0
|
||||
@ -355,6 +366,34 @@ class SessionSnapUserOperator(bpy.types.Operator):
|
||||
pass
|
||||
|
||||
|
||||
class SessionDumpDatabase(bpy.types.Operator, ExportHelper):
|
||||
bl_idname = "session.dump"
|
||||
bl_label = "dump json data"
|
||||
bl_description = "dump session stored data to a json file"
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
# ExportHelper mixin class uses this
|
||||
filename_ext = ".json"
|
||||
|
||||
filter_glob: bpy.props.StringProperty(
|
||||
default="*.json",
|
||||
options={'HIDDEN'},
|
||||
maxlen=255, # Max internal buffer length, longer would be clamped.
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def execute(self, context):
|
||||
print(self.filepath)
|
||||
if client.instance and client.instance.state() == 3:
|
||||
client.instance.dump(self.filepath)
|
||||
return {"FINISHED"}
|
||||
|
||||
return {"CANCELLED"}
|
||||
|
||||
pass
|
||||
# TODO: Rename to match official blender convention
|
||||
classes = (
|
||||
SessionJoinOperator,
|
||||
@ -365,6 +404,7 @@ classes = (
|
||||
SessionPropertyRemoveOperator,
|
||||
SessionSnapUserOperator,
|
||||
SessionPropertyRightOperator,
|
||||
SessionDumpDatabase,
|
||||
)
|
||||
|
||||
|
||||
@ -372,7 +412,7 @@ def is_replicated(update):
|
||||
object_type = update.id.bl_rna.__class__.__name__
|
||||
object_name = update.id.name
|
||||
|
||||
#Master collection special cae
|
||||
# Master collection special cae
|
||||
if update.id.name == 'Master Collection':
|
||||
object_type = 'Scene'
|
||||
object_name = bpy.context.scene.name
|
||||
@ -432,7 +472,7 @@ def depsgraph_update(scene):
|
||||
else:
|
||||
item = get_datablock_from_update(update,ctx)
|
||||
|
||||
#get parent authority
|
||||
# get parent authority
|
||||
if hasattr(item,"id"):
|
||||
parent_id = ctx.collection.id if ctx.collection.id != 'None' else ctx.scene.id
|
||||
|
||||
|
1
result.json
Normal file
1
result.json
Normal file
File diff suppressed because one or more lines are too long
35
ui.py
35
ui.py
@ -8,11 +8,11 @@ ICONS = {'Curve':'CURVE_DATA', 'Client':'SOLO_ON','Collection': 'FILE_FOLDER', '
|
||||
'Texture': 'TEXTURE_DATA', 'Scene': 'SCENE_DATA','AreaLight':'LIGHT_DATA', 'Light': 'LIGHT_DATA', 'SpotLight': 'LIGHT_DATA', 'SunLight': 'LIGHT_DATA', 'PointLight': 'LIGHT_DATA', 'Camera': 'CAMERA_DATA', 'Action': 'ACTION_DATA', 'Armature': 'ARMATURE_DATA', 'GreasePencil': 'GREASEPENCIL'}
|
||||
|
||||
class SESSION_PT_settings(bpy.types.Panel):
|
||||
bl_label = "NET settings"
|
||||
bl_idname = "SCENE_PT_SessionSettings"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
bl_idname = "MULTIUSER_SETTINGS_PT_panel"
|
||||
bl_label = "Network"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Multiuser"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -79,6 +79,10 @@ class SESSION_PT_settings(bpy.types.Panel):
|
||||
|
||||
row = layout.row()
|
||||
row.operator("session.stop", icon='QUIT', text="Exit")
|
||||
row = layout.row(align=True)
|
||||
|
||||
row.operator("session.dump", icon='QUIT', text="Dump")
|
||||
row.operator("session.dump", icon='QUIT', text="Load")
|
||||
row = layout.row()
|
||||
|
||||
box = row.box()
|
||||
@ -99,12 +103,11 @@ class SESSION_PT_settings(bpy.types.Panel):
|
||||
|
||||
|
||||
class SESSION_PT_user(bpy.types.Panel):
|
||||
bl_label = "NET users"
|
||||
bl_idname = "SCENE_PT_SessionUsers"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
|
||||
bl_idname = "MULTIUSER_USER_PT_panel"
|
||||
bl_label = "Users online"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Multiuser"
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return client.instance and client.instance.state() == 3
|
||||
@ -145,11 +148,11 @@ def get_client_key(item):
|
||||
return item[0]
|
||||
|
||||
class SESSION_PT_properties(bpy.types.Panel):
|
||||
bl_label = "NET properties"
|
||||
bl_idname = "SCENE_PT_SessionProps"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
bl_idname = "MULTIUSER_PROPERTIES_PT_panel"
|
||||
bl_label = "Replicated properties"
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "Multiuser"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
Loading…
Reference in New Issue
Block a user