# wallet.ludic - the purse, its verbs, its facts and its save section export property MoneyChanged { before: int = 0 after: int = 0 } export state WalletState { wl_money: int = 0 wl_changes: Queue = wl_changes__new() } export function wallet_changes(wallet_st: WalletState) -> Queue { return wallet_st.wl_changes } export function wallet_money(wallet_st: WalletState) -> int { return wallet_st.wl_money } export function wallet_can(wallet_st: WalletState, n: int) -> bool { return wallet_st.wl_money >= n } # the purse holds exactly n (a starting purse, a correction, the network's word) export function wallet_set(wallet_st: mut WalletState, n: int) -> void { if n == wallet_st.wl_money { return } var c = q_rec(wallet_changes(wallet_st)) if c == null { @alloc_ok("past the ring: more of these in a frame than its records, then kept in it") c = new MoneyChanged q_ring_add(wallet_changes(wallet_st), c) } c.before = wallet_st.wl_money c.after = n wallet_st.wl_money = n q_push(wallet_changes(wallet_st), c) } export function wallet_earn(wallet_st: mut WalletState, n: int) -> void { wallet_set(wallet_st, wallet_st.wl_money + n) } # only what is there: false, and nothing spent, when it is not export function wallet_spend(wallet_st: mut WalletState, n: int) -> bool { if n > wallet_st.wl_money { return false } wallet_set(wallet_st, wallet_st.wl_money - n) return true } # a cost that happens whether or not it can be paid (a rescue, a fine); never below zero export function wallet_lose(wallet_st: mut WalletState, n: int) -> void { wallet_set(wallet_st, Math.max(wallet_st.wl_money - n, 0)) } export function wallet_reset(wallet_st: mut WalletState) -> void { wallet_st.wl_money = 0 q_clear(wallet_changes(wallet_st)) } export function wallet_save(wallet_st: WalletState) -> Val { let v = Value.object() sv_put_int(v, "money", wallet_st.wl_money) return v } export function wallet_load(wallet_st: mut WalletState, v: Val, version: int) -> void { wallet_st.wl_money = sv_int(v, "money", 0) q_clear(wallet_changes(wallet_st)) } export function wallet_system() -> System { let s = system_new("wallet", PH_COMMIT) s.reset = fn wallet_reset s.save = fn wallet_save s.load = fn wallet_load return s } function wl_changes__new() -> Queue { return queue_new("wallet.changes") }