Added Glitch Room Source code to Gitty
This commit is contained in:
commit
1ac9eb5644
505 files changed
+28504
No files matched your search
@@ -0,0 +1,420 @@
|
||||
class_name RoomEditSession
|
||||
extends RefCounted
|
||||
|
||||
|
||||
signal room_changed(room: RoomDefinition)
|
||||
signal dirty_changed(is_dirty: bool)
|
||||
signal saved
|
||||
signal reverted
|
||||
|
||||
|
||||
var source_room: RoomDefinition
|
||||
var working_room: RoomDefinition
|
||||
|
||||
var is_dirty: bool = false
|
||||
|
||||
var saved_state: Dictionary = {}
|
||||
|
||||
|
||||
func begin(room: RoomDefinition) -> bool:
|
||||
if room == null:
|
||||
push_error(
|
||||
"RoomEditSession cannot begin with a null room."
|
||||
)
|
||||
return false
|
||||
|
||||
source_room = room
|
||||
_create_working_copy()
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func mark_dirty() -> void:
|
||||
|
||||
if working_room == null:
|
||||
_set_dirty(
|
||||
false
|
||||
)
|
||||
return
|
||||
|
||||
var current_state := (
|
||||
_capture_room_state(
|
||||
working_room
|
||||
)
|
||||
)
|
||||
|
||||
_set_dirty(
|
||||
current_state != saved_state
|
||||
)
|
||||
|
||||
|
||||
func save() -> bool:
|
||||
if source_room == null:
|
||||
push_error(
|
||||
"RoomEditSession has no source room."
|
||||
)
|
||||
return false
|
||||
|
||||
if working_room == null:
|
||||
push_error(
|
||||
"RoomEditSession has no working room."
|
||||
)
|
||||
return false
|
||||
|
||||
_apply_working_copy_to_source()
|
||||
|
||||
var path := source_room.resource_path
|
||||
|
||||
if path.is_empty():
|
||||
push_error(
|
||||
"Source RoomDefinition has no resource path."
|
||||
)
|
||||
return false
|
||||
|
||||
var error := ResourceSaver.save(
|
||||
source_room,
|
||||
path
|
||||
)
|
||||
|
||||
if error != OK:
|
||||
push_error(
|
||||
"Failed to save RoomDefinition. Error: %s"
|
||||
% error
|
||||
)
|
||||
return false
|
||||
|
||||
print(
|
||||
"[ROOM EDITOR] Saved room to '%s'."
|
||||
% path
|
||||
)
|
||||
|
||||
saved_state = (
|
||||
_capture_room_state(
|
||||
working_room
|
||||
)
|
||||
)
|
||||
|
||||
_set_dirty(
|
||||
false
|
||||
)
|
||||
|
||||
saved.emit()
|
||||
|
||||
return true
|
||||
|
||||
|
||||
func revert() -> void:
|
||||
|
||||
if source_room == null:
|
||||
return
|
||||
|
||||
_create_working_copy()
|
||||
|
||||
reverted.emit()
|
||||
|
||||
print(
|
||||
"[ROOM EDITOR] Reverted unsaved changes."
|
||||
)
|
||||
|
||||
func reload_from_disk() -> bool:
|
||||
|
||||
if source_room == null:
|
||||
return false
|
||||
|
||||
var path := (
|
||||
source_room.resource_path
|
||||
)
|
||||
|
||||
if path.is_empty():
|
||||
push_error(
|
||||
"Source RoomDefinition has no resource path."
|
||||
)
|
||||
return false
|
||||
|
||||
var reloaded := (
|
||||
ResourceLoader.load(
|
||||
path,
|
||||
"",
|
||||
ResourceLoader.CACHE_MODE_REPLACE
|
||||
)
|
||||
as RoomDefinition
|
||||
)
|
||||
|
||||
if reloaded == null:
|
||||
push_error(
|
||||
"Failed to reload RoomDefinition from '%s'."
|
||||
% path
|
||||
)
|
||||
return false
|
||||
|
||||
source_room = reloaded
|
||||
|
||||
_create_working_copy()
|
||||
|
||||
print(
|
||||
"[ROOM EDITOR] Reloaded room from disk: '%s'."
|
||||
% path
|
||||
)
|
||||
|
||||
return true
|
||||
|
||||
func _create_working_copy() -> void:
|
||||
|
||||
working_room = (
|
||||
_duplicate_room(
|
||||
source_room
|
||||
)
|
||||
)
|
||||
|
||||
saved_state = (
|
||||
_capture_room_state(
|
||||
working_room
|
||||
)
|
||||
)
|
||||
|
||||
_set_dirty(
|
||||
false
|
||||
)
|
||||
|
||||
room_changed.emit(
|
||||
working_room
|
||||
)
|
||||
|
||||
func _apply_working_copy_to_source() -> void:
|
||||
|
||||
for working_placement in working_room.cabinet_placements:
|
||||
if working_placement == null:
|
||||
continue
|
||||
|
||||
var source_placement := (
|
||||
source_room.get_cabinet_placement(
|
||||
working_placement.cabinet_id
|
||||
)
|
||||
)
|
||||
|
||||
if source_placement == null:
|
||||
continue
|
||||
|
||||
source_placement.position = (
|
||||
working_placement.position
|
||||
)
|
||||
|
||||
source_placement.rotation_degrees = (
|
||||
working_placement.rotation_degrees
|
||||
)
|
||||
|
||||
for working_device in working_room.devices:
|
||||
if working_device == null:
|
||||
continue
|
||||
|
||||
var source_device := (
|
||||
source_room.get_device(
|
||||
working_device.device_id
|
||||
)
|
||||
)
|
||||
|
||||
if source_device == null:
|
||||
continue
|
||||
|
||||
source_device.position = (
|
||||
working_device.position
|
||||
)
|
||||
|
||||
for working_binding in working_room.bindings:
|
||||
|
||||
if working_binding == null:
|
||||
continue
|
||||
|
||||
var source_binding: RoomDeviceBinding = null
|
||||
|
||||
for candidate in source_room.bindings:
|
||||
|
||||
if candidate == null:
|
||||
continue
|
||||
|
||||
if (
|
||||
candidate.cabinet_id
|
||||
== working_binding.cabinet_id
|
||||
and candidate.hardware_action_id
|
||||
== working_binding.hardware_action_id
|
||||
and candidate.device_id
|
||||
== working_binding.device_id
|
||||
):
|
||||
source_binding = candidate
|
||||
break
|
||||
|
||||
if source_binding == null:
|
||||
continue
|
||||
|
||||
source_binding.route_points = (
|
||||
working_binding.route_points.duplicate()
|
||||
)
|
||||
|
||||
#
|
||||
# Copy authored room geometry.
|
||||
#
|
||||
source_room.boundary_points = (
|
||||
working_room.boundary_points.duplicate()
|
||||
)
|
||||
|
||||
source_room.walls = _duplicate_walls(
|
||||
working_room.walls
|
||||
)
|
||||
|
||||
func _duplicate_room(
|
||||
source: RoomDefinition
|
||||
) -> RoomDefinition:
|
||||
|
||||
var copy := (
|
||||
source.duplicate(true)
|
||||
as RoomDefinition
|
||||
)
|
||||
|
||||
if copy == null:
|
||||
return null
|
||||
|
||||
#
|
||||
# Explicitly duplicate authored geometry so
|
||||
# wall Resources are never shared with source_room.
|
||||
#
|
||||
copy.boundary_points = (
|
||||
source.boundary_points.duplicate()
|
||||
)
|
||||
|
||||
copy.walls = _duplicate_walls(
|
||||
source.walls
|
||||
)
|
||||
|
||||
return copy
|
||||
|
||||
|
||||
func _duplicate_walls(
|
||||
source: Array[RoomWallDefinition]
|
||||
) -> Array[RoomWallDefinition]:
|
||||
|
||||
var result: Array[RoomWallDefinition] = []
|
||||
|
||||
for wall in source:
|
||||
if wall == null:
|
||||
continue
|
||||
|
||||
var copy := (
|
||||
wall.duplicate(true)
|
||||
as RoomWallDefinition
|
||||
)
|
||||
|
||||
if copy != null:
|
||||
result.append(
|
||||
copy
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
func _capture_room_state(
|
||||
room: RoomDefinition
|
||||
) -> Dictionary:
|
||||
|
||||
if room == null:
|
||||
return {}
|
||||
|
||||
var state := {
|
||||
"room_id": room.room_id,
|
||||
"display_name": room.display_name,
|
||||
"boundary_points": room.boundary_points.duplicate(),
|
||||
"cabinet_placements": [],
|
||||
"devices": [],
|
||||
"bindings": [],
|
||||
"walls": [],
|
||||
}
|
||||
|
||||
for placement in room.cabinet_placements:
|
||||
|
||||
if placement == null:
|
||||
state["cabinet_placements"].append(
|
||||
null
|
||||
)
|
||||
continue
|
||||
|
||||
state["cabinet_placements"].append(
|
||||
{
|
||||
"cabinet_id": placement.cabinet_id,
|
||||
"position": placement.position,
|
||||
"rotation_degrees": (
|
||||
placement.rotation_degrees
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
for device in room.devices:
|
||||
|
||||
if device == null:
|
||||
state["devices"].append(
|
||||
null
|
||||
)
|
||||
continue
|
||||
|
||||
state["devices"].append(
|
||||
{
|
||||
"device_id": device.device_id,
|
||||
"display_name": device.display_name,
|
||||
"device_type": device.device_type,
|
||||
"behavior": device.behavior,
|
||||
"initial_active": (
|
||||
device.initial_active
|
||||
),
|
||||
"position": device.position,
|
||||
}
|
||||
)
|
||||
|
||||
for binding in room.bindings:
|
||||
|
||||
if binding == null:
|
||||
state["bindings"].append(
|
||||
null
|
||||
)
|
||||
continue
|
||||
|
||||
state["bindings"].append(
|
||||
{
|
||||
"cabinet_id": binding.cabinet_id,
|
||||
"hardware_action_id": (
|
||||
binding.hardware_action_id
|
||||
),
|
||||
"device_id": binding.device_id,
|
||||
"route_points": (
|
||||
binding.route_points.duplicate()
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
for wall in room.walls:
|
||||
|
||||
if wall == null:
|
||||
state["walls"].append(
|
||||
null
|
||||
)
|
||||
continue
|
||||
|
||||
state["walls"].append(
|
||||
{
|
||||
"wall_id": wall.wall_id,
|
||||
"start": wall.start,
|
||||
"end": wall.end,
|
||||
"thickness": wall.thickness,
|
||||
}
|
||||
)
|
||||
|
||||
return state
|
||||
|
||||
func _set_dirty(
|
||||
value: bool
|
||||
) -> void:
|
||||
|
||||
if is_dirty == value:
|
||||
return
|
||||
|
||||
is_dirty = value
|
||||
|
||||
dirty_changed.emit(
|
||||
is_dirty
|
||||
)
|
||||
Reference in new issue
Block a user