ludic.settings: the store filled into a kept object in place; texts read from a file kept apart from it
settings_fill_json(v) writes every saved setting into an object the caller keeps, making a Value only for a key seen the first time (value_set_str / value_set_int): Maroon Lake's Settings pages rebuilt the whole tree on every change and dropped the old one. A text read from a file is interned, and so is a muted card's key ludic.hints does not know, so the parsed tree can be let go whole. Test: the store filled into a kept object changes its Values in place (6 tests pass). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1667d7f16e
commit
9c24d707bc
3 changed files with 33 additions and 2 deletions
|
|
@ -43,7 +43,7 @@ export function hints_mutes_load(hints_st: mut HintsState, l: Val) -> void {
|
|||
if Value.kind(e) != 4 { continue }
|
||||
let k = Value.as_str(e)
|
||||
let id = hints_find(k)
|
||||
if id >= 0 { hints_st.hn_mute[id] = true } else { push(hints_st.hn_foreign, k) }
|
||||
if id >= 0 { hints_st.hn_mute[id] = true } else { push(hints_st.hn_foreign, intern(k)) } # the tree is let go
|
||||
}
|
||||
}
|
||||
function hn_mutes() -> []bool {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,22 @@ export function settings_put(settings_st: SettingsState, v: Val, id: int) -> voi
|
|||
}
|
||||
}
|
||||
|
||||
# the store written into a kept object in place, in the file's own form: a Value is made only the
|
||||
# first time its key is seen (a screen reading the settings made a new tree on every change)
|
||||
export function settings_fill_json(settings_st: SettingsState, v: Val) -> void {
|
||||
for i in 0 .. len(settings_st.sg_defs) {
|
||||
let d = settings_st.sg_defs[i]
|
||||
if not d.saved { continue }
|
||||
if d.kind == SETTING_TEXT {
|
||||
value_set_str(v, d.key, settings_st.sg_text[i])
|
||||
} else if d.kind == SETTING_FLOAT {
|
||||
value_set_int(v, d.key, int(Math.floor(settings_st.sg_num[i] * 1000.0 + 0.5)))
|
||||
} else {
|
||||
value_set_int(v, d.key, int(settings_st.sg_num[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# every key `v` names, held to its range; quiet, since a load is applied whole by its caller
|
||||
export function settings_from_json(settings_st: mut SettingsState, v: Val) -> void {
|
||||
if v == null { return }
|
||||
|
|
@ -30,7 +46,7 @@ function sg_read(settings_st: mut SettingsState, v: Val, id: int) -> void {
|
|||
let d = settings_st.sg_defs[id]
|
||||
if not d.saved or Value.kind(v) != 6 or Value.has(v, d.key) == 0 { return }
|
||||
if d.kind == SETTING_TEXT {
|
||||
settings_st.sg_text[id] = sv_str(v, d.key, settings_st.sg_text[id])
|
||||
settings_st.sg_text[id] = intern(sv_str(v, d.key, settings_st.sg_text[id])) # the file's tree is let go
|
||||
} else if d.kind == SETTING_FLOAT {
|
||||
settings_st.sg_num[id] = settings_held(settings_st, id, sv_float(v, d.key, settings_st.sg_num[id]))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,21 @@ program SettingsTest {
|
|||
expect_eq(fs[1].id, TOY_LANG)
|
||||
}
|
||||
|
||||
test "the store filled into a kept object changes its Values in place" (settings_st: mut SettingsState) {
|
||||
declare(settings_st)
|
||||
let o = Value.object()
|
||||
settings_fill_json(settings_st, o)
|
||||
let q = Value.get(o, "shadow_q")
|
||||
let l = Value.get(o, "lang")
|
||||
settings_set_int(settings_st, TOY_SHADOW_Q, 3)
|
||||
settings_set_text(settings_st, TOY_LANG, "tr")
|
||||
settings_fill_json(settings_st, o)
|
||||
expect(Value.get(o, "shadow_q") == q)
|
||||
expect(Value.get(o, "lang") == l)
|
||||
expect_eq(Value.as_int(q), 3)
|
||||
expect(Value.as_str(l) == "tr")
|
||||
}
|
||||
|
||||
test "a value out of range is the default" (settings_st: mut SettingsState) {
|
||||
declare(settings_st)
|
||||
settings_set_int(settings_st, TOY_SHADOW_Q, 9)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue