firefly_rust/
stats.rs

1use crate::Peer;
2
3#[derive(Copy, Clone, Eq, PartialEq, Debug)]
4pub struct Badge(pub u8);
5
6#[derive(Copy, Clone, Eq, PartialEq, Debug)]
7pub struct Board(pub u8);
8
9#[derive(Copy, Clone, Eq, PartialEq, Debug)]
10pub struct Progress {
11    /// How many points the player already has.
12    pub done: u16,
13    /// How many points the player needs to earn the badge.
14    pub goal: u16,
15}
16
17impl Progress {
18    #[must_use]
19    pub fn earned(&self) -> bool {
20        self.done >= self.goal
21    }
22}
23
24/// Get the progress of earning the badge.
25#[must_use]
26pub fn get_progress(p: Peer, b: Badge) -> Progress {
27    add_progress(p, b, 0)
28}
29
30/// Add the given value to the progress for the badge.
31///
32/// May be negative if you want to decrease the progress.
33/// If zero, does not change the progress.
34///
35/// If the Peer is [`Peer::COMBINED`], the progress is added to every peer
36/// and the returned value is the lowest progress.
37#[expect(clippy::must_use_candidate)]
38pub fn add_progress(p: Peer, b: Badge, v: i16) -> Progress {
39    let r = unsafe { bindings::add_progress(u32::from(p.0), u32::from(b.0), i32::from(v)) };
40    Progress {
41        done: (r >> 16) as u16,
42        goal: (r) as u16,
43    }
44}
45
46/// Get the personal best of the player.
47#[must_use]
48pub fn get_score(p: Peer, b: Board) -> i16 {
49    add_score(p, b, 0)
50}
51
52/// Add the given score to the board.
53///
54/// May be negative if you want the lower scores
55/// to rank higher. Zero value is not added to the board.
56///
57/// If the Peer is [`Peer::COMBINED`], the score is added for every peer
58/// and the returned value is the lowest of their best scores.
59#[expect(clippy::must_use_candidate)]
60pub fn add_score(p: Peer, b: Board, v: i16) -> i16 {
61    let r = unsafe { bindings::add_score(u32::from(p.0), u32::from(b.0), i32::from(v)) };
62    r as i16
63}
64
65mod bindings {
66    #[link(wasm_import_module = "stats")]
67    extern {
68        pub(crate) fn add_progress(peer_id: u32, badge_id: u32, val: i32) -> u32;
69        pub(crate) fn add_score(peer_id: u32, board_id: u32, new_score: i32) -> i32;
70    }
71}