OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_union_select.gd

112 lines · gd ref:
extends Node
## GATE — THE UNION SELECTION, 5a (#120 §17.10): objects, brushes and curves held together.
##   U1  Shift adds an object to a brush selection: both are held
##   U2  ... and a curve: all three (the curve list holds it; it is the active curve)
##   U3  Shift on a held brush takes it out, the rest stays
##   U4  a plain pick replaces everything
##   U5  A holds every object, every live brush and every curve
##   U6  A again lets go of everything (2.79's A toggle)
##   U7  the outliner lights the object's row AND the brush's row together
##
## RUN AS A SCENE: "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_union_select.tscn

var fails := 0
var checks := 0
var map: Node3D
var persist: Node


func _ok(what: String, cond: bool, note: Variant = "") -> void:
	checks += 1
	if not cond:
		fails += 1
	print("  %-64s %s  %s" % [what, "OK" if cond else "**FAIL**", str(note)])


func _ready() -> void:
	var gs: Node = get_tree().root.get_node_or_null("/root/GameState")
	gs.route("world:level:*", 1, "peer")
	var keet: Node = get_tree().root.get_node_or_null("/root/KeetService")
	if keet != null:
		keet.current_member_id = "gate-author"
	get_tree().root.get_node("/root/GameMode").set_mode("build")
	map = (load("res://scenes/maps/map_dev_test.tscn") as PackedScene).instantiate()
	add_child(map)
	for i in 6:
		await get_tree().process_frame
	await _run()
	get_tree().root.get_node("/root/GameMode").set_mode("play")
	if checks < 10:
		print("  **FAIL** only %d checks ran -- setup died before the assertions" % checks)
		fails += 1
	print("\nGATE union_select: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
	get_tree().quit(0 if fails == 0 else 1)


func _brushes() -> Array:
	return map.get("_sel_brushes")


func _run() -> void:
	persist = map.get("_persist")
	var level: Node = map.get("level")
	var live: PackedInt32Array = level.get_live_brush_ids()
	var b0: int = live[0]
	var b1: int = live[1]
	var objs: Array = (map.get_node("SceneObjects").entries() as Array)
	var o0 := String(objs[0]["dot"])
	var c: String = map.create_curve([CurveMath.point(Vector3(50.13, 1, 50.11)), CurveMath.point(Vector3(53.3, 1, 50.11))],
		false, "U")
	_ok("setup: brushes, an object, a curve", live.size() >= 2 and objs.size() >= 1 and c != "")
	_ok("U the map has the union API", map.has_method("select_all") and map.has_method("selected_curves"))
	if not map.has_method("select_all"):
		return

	# ---- U1 / U2 ----
	map.select_brushes(PackedInt32Array([b0]))
	map.select_object(o0, true)
	_ok("U1 Shift adds an object to a brush selection: both held", _brushes() == [b0]
		and map.selected_objects() == [o0], [_brushes(), map.selected_objects()])
	map.select_curve(c, true)
	_ok("U2 ... and a curve: all three", _brushes() == [b0] and map.selected_objects() == [o0]
		and map.selected_curves() == [c] and map.selected_curve() == c)

	# ---- U3 ----
	map.call("_note_selected", b1, true)
	map.call("_note_selected", b0, true)
	_ok("U3 Shift on a held brush takes it out, the rest stays", _brushes() == [b1]
		and map.selected_objects() == [o0] and map.selected_curves() == [c], [_brushes(), map.selected_objects()])

	# ---- U4 ----
	map.select_object(o0)
	_ok("U4 a plain pick replaces everything", _brushes().is_empty() and map.selected_objects() == [o0]
		and map.selected_curves().is_empty())

	# ---- U5 / U6 ----
	map.clear_selection()                      # A toggles: from nothing, everything
	map.select_all()
	_ok("U5 A: every live brush", _brushes().size() == live.size(), [_brushes().size(), live.size()])
	_ok("U5 ... every object", map.selected_objects().size() == objs.size(), [map.selected_objects().size(), objs.size()])
	_ok("U5 ... every curve", map.selected_curves() == map.curve_states().keys())
	map.select_all()
	_ok("U6 A again: nothing", _brushes().is_empty() and map.selected_objects().is_empty() and map.selected_curves().is_empty())

	# ---- U7 ----
	map.select_brushes(PackedInt32Array([b0]))
	map.select_object(o0, true)
	await get_tree().process_frame
	await get_tree().process_frame
	var panel: Node = map.get("_outliner")
	var lit_obj := false
	var lit_brush := false
	var it: TreeItem = (panel.get("_tree") as Tree).get_next_selected(null)
	while it != null:
		var r: Variant = it.get_metadata(0)
		if r is Dictionary:
			if String((r as Dictionary).get("object_dot", "")) == o0:
				lit_obj = true
			if ((r as Dictionary).get("brushes", PackedInt32Array()) as PackedInt32Array).has(b0):
				lit_brush = true
		it = (panel.get("_tree") as Tree).get_next_selected(it)
	_ok("U7 the outliner lights the object's row and the brush's row", lit_obj and lit_brush, [lit_obj, lit_brush])