implement serialization system
This commit is contained in:
parent
971eac3ce0
commit
972abccfad
|
@ -56,3 +56,9 @@ func _on_click(event):
|
||||||
|
|
||||||
HomeApi.set_state(entity_id, "on" if !state else "off", attributes)
|
HomeApi.set_state(entity_id, "on" if !state else "off", attributes)
|
||||||
set_state(!state, brightness)
|
set_state(!state, brightness)
|
||||||
|
|
||||||
|
func _save():
|
||||||
|
return {
|
||||||
|
"transform": transform,
|
||||||
|
"entity_id": entity_id
|
||||||
|
}
|
|
@ -86,3 +86,9 @@ func load_image(url: String):
|
||||||
var texture = ImageTexture.create_from_image(image)
|
var texture = ImageTexture.create_from_image(image)
|
||||||
logo.texture = texture
|
logo.texture = texture
|
||||||
logo.pixel_size = pixel_size
|
logo.pixel_size = pixel_size
|
||||||
|
|
||||||
|
func _save():
|
||||||
|
return {
|
||||||
|
"transform": transform,
|
||||||
|
"entity_id": entity_id
|
||||||
|
}
|
|
@ -22,3 +22,9 @@ func set_text(stateInfo):
|
||||||
text += " " + stateInfo["attributes"]["unit_of_measurement"]
|
text += " " + stateInfo["attributes"]["unit_of_measurement"]
|
||||||
|
|
||||||
label.text = text
|
label.text = text
|
||||||
|
|
||||||
|
func _save():
|
||||||
|
return {
|
||||||
|
"transform": transform,
|
||||||
|
"entity_id": entity_id
|
||||||
|
}
|
|
@ -31,3 +31,9 @@ func _on_click(event):
|
||||||
|
|
||||||
func _on_request_completed():
|
func _on_request_completed():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
func _save():
|
||||||
|
return {
|
||||||
|
"transform": transform,
|
||||||
|
"entity_id": entity_id
|
||||||
|
}
|
|
@ -55,4 +55,3 @@ func vector_key_mapping(key_positive_x: int, key_negative_x: int, key_positive_y
|
||||||
vec = vec.normalized()
|
vec = vec.normalized()
|
||||||
|
|
||||||
return vec
|
return vec
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ func _on_entity_click(entity_name):
|
||||||
return
|
return
|
||||||
|
|
||||||
entity.set_position(global_position)
|
entity.set_position(global_position)
|
||||||
get_node("/root").add_child(entity)
|
get_node("/root/Main").add_child(entity)
|
||||||
|
|
||||||
func clear_menu():
|
func clear_menu():
|
||||||
for child in devices_node.get_children():
|
for child in devices_node.get_children():
|
||||||
|
|
|
@ -41,31 +41,32 @@ func _ready():
|
||||||
wall_mesh.visible = false
|
wall_mesh.visible = false
|
||||||
)
|
)
|
||||||
|
|
||||||
toggle_edit_button.on_button_up.connect(func():
|
toggle_edit_button.on_button_up.connect(_handle_button_up)
|
||||||
edit_enabled = false
|
|
||||||
|
|
||||||
wall_corners.visible = false
|
func _handle_button_up():
|
||||||
wall_edges.visible = false
|
edit_enabled = false
|
||||||
wall_mesh.mesh = generate_mesh()
|
|
||||||
|
|
||||||
if wall_mesh.mesh == null:
|
wall_corners.visible = false
|
||||||
return
|
wall_edges.visible = false
|
||||||
|
wall_mesh.mesh = generate_mesh()
|
||||||
|
|
||||||
var collisions = generate_collision(wall_mesh.mesh)
|
if wall_mesh.mesh == null:
|
||||||
|
return
|
||||||
|
|
||||||
for old_coll in wall_collisions.get_children():
|
var collisions = generate_collision(wall_mesh.mesh)
|
||||||
old_coll.queue_free()
|
|
||||||
|
|
||||||
for collision in collisions:
|
for old_coll in wall_collisions.get_children():
|
||||||
var static_body = StaticBody3D.new()
|
old_coll.queue_free()
|
||||||
static_body.set_collision_layer_value(4, true)
|
|
||||||
static_body.set_collision_layer_value(5, true)
|
|
||||||
static_body.collision_mask = 0
|
|
||||||
static_body.add_child(collision)
|
|
||||||
wall_collisions.add_child(static_body)
|
|
||||||
|
|
||||||
wall_mesh.visible = true
|
for collision in collisions:
|
||||||
)
|
var static_body = StaticBody3D.new()
|
||||||
|
static_body.set_collision_layer_value(4, true)
|
||||||
|
static_body.set_collision_layer_value(5, true)
|
||||||
|
static_body.collision_mask = 0
|
||||||
|
static_body.add_child(collision)
|
||||||
|
wall_collisions.add_child(static_body)
|
||||||
|
|
||||||
|
wall_mesh.visible = true
|
||||||
|
|
||||||
func generate_mesh():
|
func generate_mesh():
|
||||||
var corner_count = wall_corners.get_child_count()
|
var corner_count = wall_corners.get_child_count()
|
||||||
|
@ -200,3 +201,17 @@ func corners_to_edge_transform(from_pos: Vector3, to_pos: Vector3) -> Transform3
|
||||||
|
|
||||||
var edge_transform = Transform3D(edge_basis, edge_position)
|
var edge_transform = Transform3D(edge_basis, edge_position)
|
||||||
return edge_transform
|
return edge_transform
|
||||||
|
|
||||||
|
func _save():
|
||||||
|
return {
|
||||||
|
"corners": wall_corners.get_children().map(func(corner): return corner.position),
|
||||||
|
}
|
||||||
|
|
||||||
|
func _load(data):
|
||||||
|
for corner in data["corners"]:
|
||||||
|
add_corner(corner)
|
||||||
|
|
||||||
|
_handle_button_up()
|
||||||
|
|
||||||
|
queue_free()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
var file_url: String = "user://config.json"
|
const VariantSerializer = preload("res://lib/utils/variant_serializer.gd")
|
||||||
|
|
||||||
|
var file_url: String = "user://config.cfg"
|
||||||
|
|
||||||
func save_config(data: Dictionary):
|
func save_config(data: Dictionary):
|
||||||
var file := FileAccess.open(file_url, FileAccess.WRITE)
|
var file := FileAccess.open(file_url, FileAccess.WRITE)
|
||||||
|
@ -8,7 +10,7 @@ func save_config(data: Dictionary):
|
||||||
if file == null:
|
if file == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
var json_data := JSON.stringify(data)
|
var json_data := JSON.stringify(VariantSerializer.stringify_value(data))
|
||||||
file.store_string(json_data)
|
file.store_string(json_data)
|
||||||
|
|
||||||
func load_config():
|
func load_config():
|
||||||
|
@ -18,6 +20,6 @@ func load_config():
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
var json_data := file.get_as_text()
|
var json_data := file.get_as_text()
|
||||||
var data = JSON.parse_string(json_data)
|
var data = VariantSerializer.parse_value(JSON.parse_string(json_data))
|
||||||
|
|
||||||
return data
|
return data
|
|
@ -47,6 +47,7 @@ func start_adapter(type: String, url: String, token: String):
|
||||||
add_child(api)
|
add_child(api)
|
||||||
|
|
||||||
api.on_connect.connect(func():
|
api.on_connect.connect(func():
|
||||||
|
SaveSystem.load()
|
||||||
on_connect.emit()
|
on_connect.emit()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,3 +93,7 @@ func set_state(entity: String, state: String, attributes: Dictionary = {}):
|
||||||
func watch_state(entity: String, callback: Callable):
|
func watch_state(entity: String, callback: Callable):
|
||||||
assert(has_connected(), "Not connected")
|
assert(has_connected(), "Not connected")
|
||||||
return api.watch_state(entity, callback)
|
return api.watch_state(entity, callback)
|
||||||
|
|
||||||
|
func _notification(what):
|
||||||
|
if what == NOTIFICATION_WM_CLOSE_REQUEST || what == NOTIFICATION_WM_GO_BACK_REQUEST:
|
||||||
|
SaveSystem.save()
|
85
lib/globals/save_system.gd
Normal file
85
lib/globals/save_system.gd
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const VariantSerializer = preload("res://lib/utils/variant_serializer.gd")
|
||||||
|
|
||||||
|
func save():
|
||||||
|
if HomeApi.has_connected() == false:
|
||||||
|
return
|
||||||
|
|
||||||
|
var filename = HomeApi.api.url.split("//")[1].replace("/api/websocket", "").replace(".", "_").replace(":", "_")
|
||||||
|
|
||||||
|
var save_file = FileAccess.open("user://%s.save" % filename, FileAccess.WRITE)
|
||||||
|
|
||||||
|
if save_file == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var save_tree = _generate_save_tree(get_tree().root.get_node("Main"))
|
||||||
|
|
||||||
|
var json_text = JSON.stringify(save_tree)
|
||||||
|
save_file.store_line(json_text)
|
||||||
|
|
||||||
|
func load():
|
||||||
|
if HomeApi.has_connected() == false:
|
||||||
|
return
|
||||||
|
|
||||||
|
var filename = HomeApi.api.url.split("//")[1].replace("/api/websocket", "").replace(".", "_").replace(":", "_")
|
||||||
|
|
||||||
|
var save_file = FileAccess.open("user://%s.save" % filename, FileAccess.READ)
|
||||||
|
|
||||||
|
if save_file == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var json_text = save_file.get_line()
|
||||||
|
var save_tree = JSON.parse_string(json_text)
|
||||||
|
|
||||||
|
if save_tree is Array:
|
||||||
|
for tree in save_tree:
|
||||||
|
_build_save_tree(tree)
|
||||||
|
else:
|
||||||
|
_build_save_tree(save_tree)
|
||||||
|
|
||||||
|
|
||||||
|
func _generate_save_tree(node: Node):
|
||||||
|
var children = []
|
||||||
|
|
||||||
|
if node.has_method("_save") == false:
|
||||||
|
for child in node.get_children():
|
||||||
|
var data = _generate_save_tree(child)
|
||||||
|
|
||||||
|
if data is Array:
|
||||||
|
for child_data in data:
|
||||||
|
children.append(child_data)
|
||||||
|
else:
|
||||||
|
children.append(data)
|
||||||
|
return children
|
||||||
|
|
||||||
|
|
||||||
|
var save_tree = {
|
||||||
|
"data": VariantSerializer.stringify_value(node.call("_save")),
|
||||||
|
"parent": node.get_parent().get_path(),
|
||||||
|
"filename": node.get_scene_file_path()
|
||||||
|
}
|
||||||
|
|
||||||
|
for child in node.get_children():
|
||||||
|
var child_data = _generate_save_tree(child)
|
||||||
|
|
||||||
|
if child_data is Array:
|
||||||
|
for data in child_data:
|
||||||
|
children.append(data)
|
||||||
|
else:
|
||||||
|
children.append(child_data)
|
||||||
|
|
||||||
|
save_tree["children"] = children
|
||||||
|
|
||||||
|
return save_tree
|
||||||
|
|
||||||
|
func _build_save_tree(tree: Dictionary):
|
||||||
|
var new_object = load(tree["filename"]).instantiate()
|
||||||
|
|
||||||
|
get_node(tree["parent"]).add_child(new_object)
|
||||||
|
|
||||||
|
if new_object.has_method("_load"):
|
||||||
|
new_object.call("_load", VariantSerializer.parse_value(tree["data"]))
|
||||||
|
else:
|
||||||
|
for key in tree["data"].keys():
|
||||||
|
new_object.set(key, VariantSerializer.parse_value(tree["data"][key]))
|
79
lib/utils/variant_serializer.gd
Normal file
79
lib/utils/variant_serializer.gd
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
extends Object
|
||||||
|
|
||||||
|
static func stringify_value(value):
|
||||||
|
match typeof(value):
|
||||||
|
TYPE_DICTIONARY:
|
||||||
|
var new_dict = {}
|
||||||
|
for key in value.keys():
|
||||||
|
new_dict[key] = stringify_value(value[key])
|
||||||
|
return new_dict
|
||||||
|
TYPE_ARRAY:
|
||||||
|
return value.map(func(item):
|
||||||
|
return stringify_value(item)
|
||||||
|
)
|
||||||
|
TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING:
|
||||||
|
return value
|
||||||
|
TYPE_VECTOR2:
|
||||||
|
return {
|
||||||
|
"x": value.x,
|
||||||
|
"y": value.y,
|
||||||
|
"_type": "Vector2"
|
||||||
|
}
|
||||||
|
TYPE_VECTOR3:
|
||||||
|
return {
|
||||||
|
"x": value.x,
|
||||||
|
"y": value.y,
|
||||||
|
"z": value.z,
|
||||||
|
"_type": "Vector3"
|
||||||
|
}
|
||||||
|
TYPE_TRANSFORM3D:
|
||||||
|
return {
|
||||||
|
"origin": stringify_value(value.origin),
|
||||||
|
"basis": stringify_value(value.basis),
|
||||||
|
"_type": "Transform3D"
|
||||||
|
}
|
||||||
|
TYPE_BASIS:
|
||||||
|
return {
|
||||||
|
"x": stringify_value(value.x),
|
||||||
|
"y": stringify_value(value.y),
|
||||||
|
"z": stringify_value(value.z),
|
||||||
|
"_type": "Basis"
|
||||||
|
}
|
||||||
|
TYPE_QUATERNION:
|
||||||
|
return {
|
||||||
|
"x": value.x,
|
||||||
|
"y": value.y,
|
||||||
|
"z": value.z,
|
||||||
|
"w": value.w,
|
||||||
|
"_type": "Quaternion"
|
||||||
|
}
|
||||||
|
_:
|
||||||
|
assert(false, "Unsupported type: %s" % typeof(value))
|
||||||
|
|
||||||
|
static func parse_value(value):
|
||||||
|
if typeof(value) == TYPE_ARRAY:
|
||||||
|
return value.map(func(item):
|
||||||
|
return parse_value(item)
|
||||||
|
)
|
||||||
|
elif typeof(value) == TYPE_DICTIONARY:
|
||||||
|
if value.has("_type"):
|
||||||
|
match value["_type"]:
|
||||||
|
"Vector2":
|
||||||
|
return Vector2(value["x"], value["y"])
|
||||||
|
"Vector3":
|
||||||
|
return Vector3(value["x"], value["y"], value["z"])
|
||||||
|
"Transform3D":
|
||||||
|
return Transform3D(parse_value(value["basis"]), parse_value(value["origin"]))
|
||||||
|
"Basis":
|
||||||
|
return Basis(parse_value(value["x"]), parse_value(value["y"]), parse_value(value["z"]))
|
||||||
|
"Quaternion":
|
||||||
|
return Quaternion(value["x"], value["y"], value["z"], value["w"])
|
||||||
|
_:
|
||||||
|
assert(false, "Unsupported type: %s" % value["_type"])
|
||||||
|
else:
|
||||||
|
var new_dict = {}
|
||||||
|
for key in value.keys():
|
||||||
|
new_dict[key] = parse_value(value[key])
|
||||||
|
return new_dict
|
||||||
|
else:
|
||||||
|
return value
|
|
@ -23,6 +23,7 @@ Request="*res://lib/globals/request.gd"
|
||||||
HomeApi="*res://lib/globals/home_api.gd"
|
HomeApi="*res://lib/globals/home_api.gd"
|
||||||
AudioPlayer="*res://lib/globals/audio_player.gd"
|
AudioPlayer="*res://lib/globals/audio_player.gd"
|
||||||
EventSystem="*res://lib/globals/event_system.gd"
|
EventSystem="*res://lib/globals/event_system.gd"
|
||||||
|
SaveSystem="*res://lib/globals/save_system.gd"
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user