P08-03: 配置の通常操作受入
This commit is contained in:
Vendored
+74
-4
@@ -18,6 +18,9 @@ var target := Vector3i(-8, 0, 0)
|
||||
var budget: Dictionary = {}
|
||||
var input_method := "handler"
|
||||
var observed_cell: Variant = null
|
||||
var save_serial := 0
|
||||
var save_records: Array = []
|
||||
const INITIAL_SAVE := "user://saves/p08_initial"
|
||||
|
||||
func annotate(row: Dictionary) -> void:
|
||||
row["input_method"] = input_method
|
||||
@@ -69,6 +72,8 @@ func button(node: BaseButton) -> void:
|
||||
expect(node != null and not node.disabled, "available production button")
|
||||
if node == null or node.disabled:
|
||||
return
|
||||
if node.toggle_mode:
|
||||
node.button_pressed = not node.button_pressed
|
||||
node.pressed.emit()
|
||||
await frames()
|
||||
|
||||
@@ -77,7 +82,9 @@ func choose(id: StringName) -> void:
|
||||
await button(main.palette_toggle_button)
|
||||
var node: Button = main.build_buttons[id]
|
||||
await reveal(node)
|
||||
await button(node)
|
||||
if not node.button_pressed:
|
||||
await button(node)
|
||||
expect(node.button_pressed and main._selected_definition_id == id, "chosen production definition")
|
||||
|
||||
func click(cell: Vector3i) -> Dictionary:
|
||||
var view: WorldPreview = main.world_preview
|
||||
@@ -253,6 +260,7 @@ func run(p_tree: SceneTree, output: String, requested_role: String) -> Dictionar
|
||||
expect(DirAccess.make_dir_recursive_absolute(directory) == OK, "diagnostic directory")
|
||||
runtime = tree.root.get_node("SimulationRuntime")
|
||||
clock = tree.root.get_node("GameClock")
|
||||
runtime.save_operation_completed.connect(record_save_operation)
|
||||
await setup()
|
||||
runtime.command_completed.connect(observe)
|
||||
main.world_preview.cell_clicked.connect(selected_cell)
|
||||
@@ -265,10 +273,12 @@ func run(p_tree: SceneTree, output: String, requested_role: String) -> Dictionar
|
||||
if requested_role == "standalone":
|
||||
role = "reader"
|
||||
actions = []
|
||||
save_records = []
|
||||
await reader(false)
|
||||
json_file(role + "-actions.json", {"setup": "diagnostic", "input_method": input_method, "actions": actions})
|
||||
finish_observations()
|
||||
runtime.command_completed.disconnect(observe)
|
||||
runtime.save_operation_completed.disconnect(record_save_operation)
|
||||
var cleanup: Dictionary = await Cleanup.free_owner_and_wait(tree, main)
|
||||
expect(cleanup.get(&"passed", false), "ordinary Main/audio cleanup")
|
||||
json_file(role + "-process.json", {"pid": OS.get_process_id(), "engine": Engine.get_version_info(), "checks": checks, "failures": failures, "role": requested_role, "setup": "diagnostic"})
|
||||
@@ -296,18 +306,78 @@ func setup() -> void:
|
||||
clock.set_paused(true)
|
||||
tree.root.size = Vector2i(1440, 810)
|
||||
main = load("res://scenes/main/main.tscn").instantiate()
|
||||
main.manual_save_path = directory.path_join("formal")
|
||||
main.manual_save_path = "user://saves/manual_ui"
|
||||
if role == "reader":
|
||||
import_package(directory.path_join("formal"), String(main.manual_save_path))
|
||||
tree.root.add_child(main)
|
||||
runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
|
||||
|
||||
func save_initial_fixture() -> void:
|
||||
# Explicit diagnostic input, not an OS action or natural-play save.
|
||||
var saved: Dictionary = SaveService.save_snapshot(directory.path_join("initial-formal"), runtime.create_snapshot())
|
||||
var saved: Dictionary = SaveService.save_snapshot(INITIAL_SAVE, runtime.create_snapshot())
|
||||
record_save_result("initial_save", INITIAL_SAVE, saved)
|
||||
expect(bool(saved.get("ok", false)), "diagnostic initial formal save")
|
||||
export_package(INITIAL_SAVE, "initial-formal")
|
||||
# Seed the private normal slot, so its later normal save produces a backup.
|
||||
import_package(ProjectSettings.globalize_path(INITIAL_SAVE), String(main.manual_save_path))
|
||||
json_file("diagnostic-budget.json", budget)
|
||||
|
||||
func archive_formal() -> void:
|
||||
pass
|
||||
export_package(String(main.manual_save_path), "formal")
|
||||
|
||||
func record_save_operation(result: Dictionary) -> void:
|
||||
record_save_result("runtime_operation", String(main.manual_save_path), result)
|
||||
|
||||
func record_save_result(operation: String, path: String, result: Dictionary) -> void:
|
||||
save_serial += 1
|
||||
var stem := "%s-save-result-%04d" % [role, save_serial]
|
||||
var raw := FileAccess.open(directory.path_join(stem + ".var"), FileAccess.WRITE)
|
||||
expect(raw != null, "raw save result")
|
||||
if raw != null:
|
||||
raw.store_buffer(var_to_bytes(result))
|
||||
raw.close()
|
||||
json_file(stem + ".json", {"pid": OS.get_process_id(), "operation": operation,
|
||||
"requested_path": path, "absolute_path": ProjectSettings.globalize_path(path),
|
||||
"user_data_dir": OS.get_user_data_dir(), "result": Codec.new().typed(result),
|
||||
"raw_sha256": FileAccess.get_sha256(directory.path_join(stem + ".var"))})
|
||||
save_records.append(stem)
|
||||
json_file(role + "-save-results.json", {"pid": OS.get_process_id(), "records": save_records})
|
||||
|
||||
func import_package(source: String, destination: String) -> void:
|
||||
var absolute := ProjectSettings.globalize_path(destination)
|
||||
expect(DirAccess.make_dir_recursive_absolute(absolute) == OK, "private save directory")
|
||||
for member: String in MEMBERS:
|
||||
var origin := source.path_join(member)
|
||||
var copy := absolute.path_join(member)
|
||||
expect(DirAccess.copy_absolute(origin, copy) == OK, "private save input " + member)
|
||||
expect(FileAccess.get_sha256(origin) == FileAccess.get_sha256(copy), "private save input SHA " + member)
|
||||
|
||||
func export_package(path: String, name: String) -> void:
|
||||
var absolute := ProjectSettings.globalize_path(path)
|
||||
var pins := {}
|
||||
for suffix: String in ["", ".bak"]:
|
||||
var source := absolute + suffix
|
||||
var present := DirAccess.dir_exists_absolute(source)
|
||||
pins[name + suffix] = {"source_path": source, "present": present, "members": {}}
|
||||
if not present:
|
||||
expect(not suffix.is_empty(), "formal package exists")
|
||||
continue
|
||||
var destination := directory.path_join(name + suffix)
|
||||
expect(DirAccess.make_dir_recursive_absolute(destination) == OK, "export directory")
|
||||
for member: String in MEMBERS:
|
||||
var origin := source.path_join(member)
|
||||
var copy := destination.path_join(member)
|
||||
expect(DirAccess.copy_absolute(origin, copy) == OK, "export " + member)
|
||||
var digest := FileAccess.get_sha256(origin)
|
||||
expect(not digest.is_empty() and digest == FileAccess.get_sha256(copy), "export SHA " + member)
|
||||
pins[name + suffix]["members"][member] = {"sha256": digest, "bytes": FileAccess.get_file_as_bytes(copy).size()}
|
||||
# Slot metadata lives in the existing manifest; copy it verbatim.
|
||||
var metadata := absolute.path_join("manifest.json")
|
||||
var metadata_copy := directory.path_join(name + "-slot-metadata.json")
|
||||
expect(DirAccess.copy_absolute(metadata, metadata_copy) == OK, "slot metadata export")
|
||||
json_file(name + "-export.json", {"pid": OS.get_process_id(), "requested_path": path,
|
||||
"absolute_path": absolute, "user_data_dir": OS.get_user_data_dir(), "packages": pins,
|
||||
"slot_metadata": {"file": name + "-slot-metadata.json", "sha256": FileAccess.get_sha256(metadata_copy)}})
|
||||
|
||||
func finish_observations() -> void:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user