Fix bill-editor crash on mode-change and remove

The mode OptionButton and remove Button both called _populate_bills()
from inside their own signal callbacks. _populate_bills() rebuilds the
bill list — freeing the very widget mid-emit, which crashes Godot.

Defer the rebuild via call_deferred("_populate_bills") so it runs
after the signal frame completes. Reproduced by user changing a bill
from FOREVER → "Do until 10".
This commit is contained in:
megaproxy 2026-05-16 00:35:42 +01:00
parent aba8476285
commit 4e09dea03a

View file

@ -292,9 +292,10 @@ func _make_bill_row(bill: Bill) -> VBoxContainer:
mode_btn.item_selected.connect(func(idx: int) -> void:
bill.mode = idx as Bill.Mode
Audit.log("workbench_ui", "%s: bill mode → %d" % [current_workbench.label_text, idx])
# Repopulate so conditional rows update; OptionButton state survives because
# we set mode on bill before the rebuild, and the new row reads bill.mode.
_populate_bills()
# Defer the rebuild — we must NOT free mode_btn while its item_selected
# signal is still emitting (instant crash). call_deferred runs the
# repopulate after the signal frame completes.
call_deferred("_populate_bills")
)
mode_row.add_child(mode_btn)
@ -366,7 +367,8 @@ func _make_bill_row(bill: Bill) -> VBoxContainer:
current_workbench.label_text,
bill.recipe.id if bill.recipe != null else "null"
])
_populate_bills()
# Defer — same reason as mode_btn: don't free this button mid-emit.
call_deferred("_populate_bills")
)
remove_row.add_child(remove_btn)