feat(runtime): integrate settings service boundary

Co-Authored-By: Codex <noreply@anthropic.com>
This commit is contained in:
2026-08-25 10:20:18 +08:00
co-authored by Codex
parent 60614149db
commit 8a8fb33c19
3 changed files with 261 additions and 19 deletions
+95 -19
View File
@@ -2,7 +2,9 @@ class_name ABGEntryShell
extends Control
const BootService = preload("res://entry/boot_service.gd")
const SettingsStore = preload("res://entry/settings_store.gd")
const SettingsServiceScript = preload("res://foundation/settings_service.gd")
const AppServicesScript = preload("res://foundation/app_services.gd")
const ScreenContextScript = preload("res://foundation/screen_context.gd")
const EntryChrome = preload("res://entry/entry_chrome.gd")
const InitialCompanyArt = preload("res://entry/initial_company_art.gd")
const GuildDestinationSticker = preload("res://entry/guild_destination_sticker.gd")
@@ -91,7 +93,14 @@ signal boot_completed
@export var auto_start := true
var boot_service := BootService.new()
var settings_store := SettingsStore.new()
var settings_service := SettingsServiceScript.new()
## Compatibility alias for existing focused fixtures. New page code should use
## `settings_service` or resolve the service through `app_services`.
var settings_store:
get: return settings_service
set(value): settings_service = value
var app_services = AppServicesScript.new({"settings": settings_service})
var settings_context
var initial_company_service := InitialCompanyDraftService.new()
var guild_contract_service := GuildContractService.new()
var formation_risk_service := FormationRiskService.new()
@@ -569,7 +578,7 @@ func _step_text(step: String) -> String:
func _open_after_boot() -> void:
var loaded: Dictionary = settings_store.load_settings()
var loaded: Dictionary = settings_service.load_settings()
if not loaded.ok:
boot_snapshot = {"state": "error", "step": "preferences", "code": String(loaded.code), "completed": 0, "total": 1}
_build_boot_screen()
@@ -589,7 +598,7 @@ func _open_after_boot() -> void:
func show_first_launch() -> void:
setup_draft = settings.duplicate(true) if not settings.is_empty() else settings_store.defaults()
setup_draft = settings.duplicate(true) if not settings.is_empty() else settings_service.defaults()
for child in get_children():
child.free()
first_launch_setting_buttons.clear()
@@ -922,7 +931,7 @@ func toggle_setup_locale() -> void:
func cycle_setup_safe_area() -> void:
var options := SettingsStore.SAFE_AREA_PRESETS
var options := SettingsServiceScript.SAFE_AREA_PRESETS
var next := (options.find(int(setup_draft.safe_area)) + 1) % options.size()
setup_draft.safe_area = options[next]
settings = setup_draft.duplicate(true)
@@ -930,7 +939,7 @@ func cycle_setup_safe_area() -> void:
func cycle_setup_text_scale() -> void:
var options := SettingsStore.TEXT_SCALES
var options := SettingsServiceScript.TEXT_SCALES
var current := 0
for index in range(options.size()):
if is_equal_approx(float(setup_draft.text_scale), float(options[index])):
@@ -975,7 +984,7 @@ func toggle_setup_captions() -> void:
func apply_first_launch() -> void:
setup_draft.setup_completed = true
var saved: Dictionary = settings_store.save_settings(setup_draft)
var saved: Dictionary = settings_service.save_settings(setup_draft)
if not saved.ok:
var error := first_launch_error
if error != null:
@@ -8151,12 +8160,73 @@ func show_credits_placeholder() -> void:
show_credits()
func _settings_return_screen_id() -> String:
match settings_caller:
"guild_handoff": return "guild_handoff"
"readiness": return "readiness_review"
"risk_board": return "risk_board"
"risk_commitment": return "risk_commitment"
"market": return "market"
"battle_opening": return "battle"
"battle_live", "battle_pause_controls": return "battle"
return "title"
func _settings_return_focus_path() -> String:
match settings_caller:
"guild_handoff": return "GuildSettings"
"readiness": return "ReadinessSettings"
"risk_board": return "RiskSettings"
"risk_commitment": return "RiskCommitmentSettings"
"market": return "MarketSettings"
"battle_opening": return "BattleOpeningSettings"
"battle_live", "battle_pause_controls": return "BattleLiveSettings"
return "TitleSettings"
func _open_settings_context() -> void:
settings_context = ScreenContextScript.new({
"screen_id": "settings",
"caller_id": settings_caller,
"return_screen_id": _settings_return_screen_id(),
"return_focus_path": _settings_return_focus_path(),
"presentation_mode": "page",
"metadata": {"category": settings_category},
})
var current = app_services.screen_stack.current()
if current != null and String(current.screen_id) == "settings":
app_services.screen_stack.replace(settings_context)
else:
app_services.screen_stack.push(settings_context)
func _close_settings_context() -> Variant:
var context = settings_context
settings_context = null
var current = app_services.screen_stack.current()
if current != null and String(current.screen_id) == "settings":
app_services.screen_stack.pop()
return context
func _restore_settings_focus(focus_name: String) -> void:
if focus_name.is_empty():
return
var target := find_child(focus_name, true, false) as Control
if target == null or target.focus_mode == Control.FOCUS_NONE:
return
if target is BaseButton and (target as BaseButton).disabled:
return
target.grab_focus()
func show_settings(category := "") -> void:
current_screen = "settings"
if settings_draft.is_empty() or not category.is_empty():
settings_draft = settings.duplicate(true)
if not category.is_empty():
settings_category = category
_open_settings_context()
current_screen = "settings"
_build_world_base()
var safe := MarginContainer.new()
safe.name = "SettingsSafeArea"
@@ -8311,28 +8381,34 @@ func discard_settings() -> void:
func _return_from_settings() -> void:
if settings_caller == "guild_handoff":
var context = _close_settings_context()
var caller := settings_caller
if context != null and not String(context.caller_id).is_empty():
caller = String(context.caller_id)
if caller == "guild_handoff":
show_guild_handoff(guild_company)
elif settings_caller == "readiness":
elif caller == "readiness":
show_readiness_review(guild_company)
elif settings_caller == "risk_board":
elif caller == "risk_board":
show_risk_board(guild_company)
elif settings_caller == "risk_commitment":
elif caller == "risk_commitment":
show_risk_commitment(guild_company)
elif settings_caller == "market":
elif caller == "market":
show_market(guild_company)
elif settings_caller == "battle_opening":
elif caller == "battle_opening":
show_battle_opening(guild_company, false)
elif settings_caller == "battle_live":
elif caller == "battle_live":
_battle_live_return_from_settings()
elif settings_caller == "battle_pause_controls":
elif caller == "battle_pause_controls":
_battle_live_return_from_settings()
else:
back_to_title()
if context != null:
call_deferred("_restore_settings_focus", String(context.return_focus_path))
func apply_settings() -> void:
var saved: Dictionary = settings_store.save_settings(settings_draft)
var saved: Dictionary = settings_service.save_settings(settings_draft)
if not saved.ok:
settings_notice = _tr("设置保存失败,请重试。", "Settings save failed. Retry.") + " [%s]" % String(saved.code)
show_settings()
@@ -8370,12 +8446,12 @@ func _apply_runtime_settings() -> void:
func cycle_setting_safe_area() -> void:
settings_draft.safe_area = _next_value(SettingsStore.SAFE_AREA_PRESETS, int(settings_draft.safe_area))
settings_draft.safe_area = _next_value(SettingsServiceScript.SAFE_AREA_PRESETS, int(settings_draft.safe_area))
show_settings()
func cycle_setting_text_scale() -> void:
settings_draft.text_scale = _next_float(SettingsStore.TEXT_SCALES, float(settings_draft.text_scale))
settings_draft.text_scale = _next_float(SettingsServiceScript.TEXT_SCALES, float(settings_draft.text_scale))
show_settings()