fix(review-batch2): 视图信号可审计性+封装收口——生产24处lambda转命名方法含bind两处(P1-3)+recent_summaries/hero_effects值拷贝出户(P2-3);生产lambda审计归零(83→59全smoke),冒烟576/0同基线

This commit is contained in:
DKChan committed 2026-09-29 06:21:32 +08:00
1 parent 463baac08e
commit f5edb65d25
13 files changed
+127 -31

No files matched your search

+1 -1
View File
@@ -786,7 +786,7 @@ func presentation_snapshot() -> Dictionary:
"can_refresh": can_refresh(),
"hero": hero,
"enemies": enemies,
"hero_effects": _status_effects.query_active("hero"),
"hero_effects": _status_effects.query_active("hero").duplicate(true), # 值拷贝出户(code-review 2026-09-29 P2-3——快照消费方直改不渗入状态容器)
}
+1 -1
View File
@@ -183,7 +183,7 @@ func boss_first_kill_marked(level_index: int) -> bool:
func recent_summaries() -> Array:
return _data["meta"]["recent_summaries"]
return _data["meta"]["recent_summaries"].duplicate(true) # 值拷贝出户(本类契约「禁碰内部结构」——消费方直改不得渗入存档内存态)
# 域更新原语(正式冒险收束唯一入账口——组合根经本函数入账,禁直改内部结构):
+6 -2
View File
@@ -53,10 +53,14 @@ func log_path() -> String:
func attach_battle(settlement) -> void:
settlement.step_row.connect(_on_step_row)
settlement.settlement_snapshot.connect(_on_settlement_snapshot)
settlement.battle_finished.connect(func(p): _append({
settlement.battle_finished.connect(_on_battle_finished_log)
func _on_battle_finished_log(p: Dictionary) -> void:
_append({
"kind": "battle_end", "result": String(p.get("result", "")),
"hero_hp": int(p.get("hero_hp", 0)),
"gp_dropped": int(p.get("gp_dropped", 0))})) # 战斗掉落列(GP+商店房实施批 2026-09-21——验收取数面)
"gp_dropped": int(p.get("gp_dropped", 0))}) # 战斗掉落列(GP+商店房实施批 2026-09-21——验收取数面)
# ---- GP 钱包行(GP+商店房实施批——到账/购买/清零事件;runner wallet_changed 投影经组合根转发)----
+10 -2
View File
@@ -55,7 +55,7 @@ func _init() -> void:
_btn_stop = UiKit.button("停手")
_btn_stop.custom_minimum_size = Vector2(64, 0)
_btn_stop.size_flags_vertical = Control.SIZE_SHRINK_CENTER
_btn_stop.pressed.connect(func(): stop_pressed.emit())
_btn_stop.pressed.connect(_emit_stop_pressed)
row.add_child(_btn_stop)
var spacer := Control.new()
@@ -91,7 +91,7 @@ func _init() -> void:
_btn_legend = UiKit.button("图例")
_btn_legend.custom_minimum_size = Vector2(56, 0)
_btn_legend.size_flags_vertical = Control.SIZE_SHRINK_CENTER
_btn_legend.pressed.connect(func(): legend_toggled.emit())
_btn_legend.pressed.connect(_emit_legend_toggled)
row.add_child(_btn_legend)
var refresh_box := VBoxContainer.new()
@@ -237,3 +237,11 @@ func _make_dot() -> ColorRect:
d.color = COL_DOT_OFF
d.mouse_filter = Control.MOUSE_FILTER_IGNORE
return d
func _emit_stop_pressed() -> void:
stop_pressed.emit()
func _emit_legend_toggled() -> void:
legend_toggled.emit()
+10 -2
View File
@@ -43,10 +43,10 @@ func _init() -> void:
_gp_line.visible = false
box.add_child(_gp_line)
_review_btn = UiKit.button("明细回看")
_review_btn.pressed.connect(func(): review_pressed.emit())
_review_btn.pressed.connect(_emit_review_pressed)
box.add_child(_review_btn)
_btn = UiKit.button("继续")
_btn.pressed.connect(func(): continue_pressed.emit())
_btn.pressed.connect(_emit_continue_pressed)
box.add_child(_btn)
# 金蜡封占位(胜利):圆形色块落于扫雷图区中央——位置由 set_board_rect 注入
_seal = Panel.new()
@@ -192,3 +192,11 @@ func _clear_crest_bricks() -> void:
# 演出探针出口(fx_probe——胜利纹章/失败掸灰/旗光收回三断言面)
func fx_probe() -> Dictionary:
return {"crest_shards": _fx_crest_shards, "dust_motes": _fx_dust_motes, "flag_dots": _fx_flag_dots}
func _emit_review_pressed() -> void:
review_pressed.emit()
func _emit_continue_pressed() -> void:
continue_pressed.emit()
+37 -7
View File
@@ -11,6 +11,7 @@ var ap_bar: ApBarView
var board_view: BoardView
var toast: ToastStack
var fx: BoardFxView
var _board_area: Control # resized 命名转发用(原 lambda 局部捕获——P1-3 转命名 2026-09-29)
signal action_requested(cell: Vector2i, kind: String)
signal stop_pressed
@@ -31,7 +32,8 @@ func _init() -> void:
board_area.size_flags_vertical = Control.SIZE_EXPAND_FILL
board_area.clip_contents = true
vb.add_child(board_area)
board_area.resized.connect(func(): board_view.set_cell_area(board_area.size))
_board_area = board_area
board_area.resized.connect(_on_board_area_resized)
board_view = BoardView.new()
board_view.set_anchors_preset(Control.PRESET_FULL_RECT)
board_area.add_child(board_view)
@@ -40,11 +42,39 @@ func _init() -> void:
toast = ToastStack.new()
board_area.add_child(toast)
# 信号转发(组合根只接线一处)
board_view.action_requested.connect(func(c: Vector2i, kind: String): action_requested.emit(c, kind))
board_view.hover_forbidden.connect(func(c: Vector2i): hover_forbidden.emit(c))
board_view.chord_attempted.connect(func(c: Vector2i): chord_attempted.emit(c))
ap_bar.stop_pressed.connect(func(): stop_pressed.emit())
ap_bar.refresh_confirmed.connect(func(): refresh_confirmed.emit())
ap_bar.legend_toggled.connect(func(): legend_toggled.emit())
board_view.action_requested.connect(_forward_action)
board_view.hover_forbidden.connect(_forward_hover)
board_view.chord_attempted.connect(_forward_chord)
ap_bar.stop_pressed.connect(_emit_stop_pressed)
ap_bar.refresh_confirmed.connect(_emit_refresh_confirmed)
ap_bar.legend_toggled.connect(_emit_legend_toggled)
func _on_board_area_resized() -> void:
board_view.set_cell_area(_board_area.size)
func _forward_action(c: Vector2i, kind: String) -> void:
action_requested.emit(c, kind)
func _forward_hover(c: Vector2i) -> void:
hover_forbidden.emit(c)
func _forward_chord(c: Vector2i) -> void:
chord_attempted.emit(c)
func _emit_stop_pressed() -> void:
stop_pressed.emit()
func _emit_refresh_confirmed() -> void:
refresh_confirmed.emit()
func _emit_legend_toggled() -> void:
legend_toggled.emit()
+10 -2
View File
@@ -84,7 +84,7 @@ func _init() -> void:
scroll.add_child(_recent_list)
var close_btn := UiKit.button("关闭营地(回开始界面)")
close_btn.pressed.connect(func(): closed.emit())
close_btn.pressed.connect(_emit_closed)
box.add_child(close_btn)
visible = false
@@ -168,7 +168,7 @@ func _build_forge_row(holder: VBoxContainer, row: Dictionary) -> Dictionary:
price_l.custom_minimum_size = Vector2(150, 0)
line.add_child(price_l)
var btn := UiKit.button("锻造 +1 级")
btn.pressed.connect(func(): buy_requested.emit(attr))
btn.pressed.connect(_emit_buy_requested.bind(attr))
line.add_child(btn)
holder.add_child(card)
return {"attr": attr, "level_l": level_l, "price_l": price_l, "btn": btn}
@@ -211,3 +211,11 @@ func _rebuild_recent(data: Dictionary) -> void:
lines.append("%s · 通关 %d 关 · 钥石 +%d · 种子 %d" % [verdict,
int(s.get("levels_cleared", 0)), int(s.get("keystone_total", 0)), int(s.get("master_seed", 0))])
_recent_list.text = "\n".join(lines)
func _emit_closed() -> void:
closed.emit()
func _emit_buy_requested(attr: String) -> void:
buy_requested.emit(attr)
+6 -3
View File
@@ -25,9 +25,7 @@ func _init() -> void:
var dim := ColorRect.new()
dim.color = Color(UiKit.DIM, 0.55)
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
dim.gui_input.connect(func(ev: InputEvent):
if ev is InputEventMouseButton and ev.pressed:
close())
dim.gui_input.connect(_on_dim_gui_input)
add_child(dim)
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
@@ -83,3 +81,8 @@ func close() -> void:
return
visible = false
closed.emit()
func _on_dim_gui_input(ev: InputEvent) -> void:
if ev is InputEventMouseButton and ev.pressed:
close()
+5 -1
View File
@@ -27,7 +27,7 @@ func _init() -> void:
_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
box.add_child(_label)
_btn = UiKit.button("继续")
_btn.pressed.connect(func(): continue_pressed.emit())
_btn.pressed.connect(_emit_continue_pressed)
box.add_child(_btn)
visible = false
@@ -49,3 +49,7 @@ func show_rest(healed: int, hp_after: int, max_hp: int) -> void:
# 探针复用:以真实按钮路径触发继续
func press_continue() -> void:
_btn.pressed.emit()
func _emit_continue_pressed() -> void:
continue_pressed.emit()
@@ -14,9 +14,7 @@ func _init() -> void:
var dim := ColorRect.new()
dim.color = Color(UiKit.DIM, 0.62)
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
dim.gui_input.connect(func(ev: InputEvent):
if ev is InputEventMouseButton and ev.pressed:
close())
dim.gui_input.connect(_on_dim_gui_input)
add_child(dim)
var center := CenterContainer.new()
center.set_anchors_preset(Control.PRESET_FULL_RECT)
@@ -55,3 +53,8 @@ func close() -> void:
return
visible = false
closed.emit()
func _on_dim_gui_input(ev: InputEvent) -> void:
if ev is InputEventMouseButton and ev.pressed:
close()
+10 -2
View File
@@ -41,7 +41,7 @@ func _init() -> void:
_cards_box.add_theme_constant_override("separation", 8)
box.add_child(_cards_box)
var leave_btn := UiKit.button("离开商店")
leave_btn.pressed.connect(func(): leave_pressed.emit())
leave_btn.pressed.connect(_emit_leave_pressed)
box.add_child(leave_btn)
visible = false
@@ -90,7 +90,7 @@ func _build_card(p: Dictionary) -> Dictionary:
bought_l.add_theme_color_override("font_color", UiKit.WARM_FAINT)
row.add_child(bought_l)
var btn := UiKit.button("购买")
btn.pressed.connect(func(): buy_requested.emit(String(p.product_id)))
btn.pressed.connect(_emit_buy_requested.bind(p))
row.add_child(btn)
_cards_box.add_child(card)
return {"product_id": String(p.product_id), "price": price_l, "bought": bought_l, "btn": btn}
@@ -100,3 +100,11 @@ func _build_card(p: Dictionary) -> Dictionary:
func _card_title(p: Dictionary) -> String:
var attr := String(p.get("attr", ""))
return "%s(%s %+d)" % [String(p.get("display_name", "")), String(ATTR_LABELS.get(attr, attr)), int(p.get("flat_value", 0))]
func _emit_leave_pressed() -> void:
leave_pressed.emit()
func _emit_buy_requested(p: Dictionary) -> void:
buy_requested.emit(String(p.product_id))
+5 -1
View File
@@ -113,7 +113,7 @@ func _make_slot() -> PanelContainer:
slot.custom_minimum_size = Vector2(50, 46)
slot.add_theme_stylebox_override("panel", UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER))
slot.mouse_entered.connect(_on_slot_hover.bind(slot))
slot.mouse_exited.connect(func(): _tip.visible = false)
slot.mouse_exited.connect(_hide_tip)
var col := VBoxContainer.new()
col.alignment = BoxContainer.ALIGNMENT_CENTER
if compact:
@@ -196,3 +196,7 @@ func _icon_tex(effect_id: String) -> Texture2D:
push_error("[状态槽] 未知图标键(映射表外键——立即断言): %s" % effect_id)
assert(false, "未知图标键: " + effect_id)
return null
func _hide_tip() -> void:
_tip.visible = false
+20 -4
View File
@@ -165,7 +165,7 @@ func _build() -> void:
motion_row.add_child(UiKit.label("减动效(动画时长减半——运动敏感/演示用)", 14, false))
var motion_btn := CheckButton.new()
motion_btn.button_pressed = UiKit.motion_scale < 1.0
motion_btn.toggled.connect(func(on: bool): UiKit.motion_scale = 0.5 if on else 1.0)
motion_btn.toggled.connect(_on_motion_toggled)
motion_row.add_child(motion_btn)
box.add_child(HSeparator.new())
@@ -181,7 +181,7 @@ func _build() -> void:
sim_row.add_child(_sim_count)
sim_row.add_child(UiKit.label("次(理性玩家策略,含面板当前加成)", 13, false))
_sim_btn = UiKit.button("运行模拟")
_sim_btn.pressed.connect(func(): simulate_requested.emit(int(_sim_count.value)))
_sim_btn.pressed.connect(_emit_simulate_requested)
sim_row.add_child(_sim_btn)
_sim_out = RichTextLabel.new()
_sim_out.bbcode_enabled = true
@@ -189,7 +189,7 @@ func _build() -> void:
box.add_child(_sim_out)
var close_btn := UiKit.button("关闭")
close_btn.pressed.connect(func(): closed.emit())
close_btn.pressed.connect(_emit_closed)
box.add_child(close_btn)
@@ -206,7 +206,7 @@ func _slider_row(box: VBoxContainer, title: String) -> Dictionary:
var v := UiKit.label("+0%", 15, true)
v.custom_minimum_size = Vector2(70, 0)
row.add_child(v)
s.value_changed.connect(func(_value: float): _sync_labels())
s.value_changed.connect(_on_slider_value_changed)
return {"slider": s, "value_label": v}
@@ -219,3 +219,19 @@ func _sync_labels() -> void:
func _scaled(base: int, pct: int) -> int:
return maxi(1, int(round(float(base) * (100.0 + float(pct)) / 100.0)))
func _on_motion_toggled(on: bool) -> void:
UiKit.motion_scale = 0.5 if on else 1.0
func _emit_simulate_requested() -> void:
simulate_requested.emit(int(_sim_count.value))
func _emit_closed() -> void:
closed.emit()
func _on_slider_value_changed(_value: float) -> void:
_sync_labels()