bms_rs/bms/model/
speed.rs

1//! This module introduces struct [`SpeedObjects`], which manages definitions and events of spacing change.
2
3use std::collections::{BTreeMap, HashMap, btree_map::Entry};
4
5use crate::{
6    bms::{error::Result, prelude::*},
7    parse::prompt::ChannelDuplication,
8};
9
10#[derive(Debug, Default, Clone, PartialEq, Eq)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12/// This aggregate manages definitions and events of spacing change.
13pub struct SpeedObjects {
14    /// Spacing change definitions, indexed by [`ObjId`]. `#SPEED[01-ZZ]`
15    pub speed_defs: HashMap<ObjId, Decimal>,
16    /// The spacing factors corresponding to the id of the spacing change object.
17    pub speed_factor_changes: BTreeMap<ObjTime, SpeedObj>,
18}
19
20impl SpeedObjects {
21    /// Adds a new spacing factor change object to the notes.
22    pub fn push_speed_factor_change(
23        &mut self,
24        speed_factor_change: SpeedObj,
25        prompt_handler: &impl Prompter,
26    ) -> Result<()> {
27        match self.speed_factor_changes.entry(speed_factor_change.time) {
28            Entry::Vacant(entry) => {
29                entry.insert(speed_factor_change);
30                Ok(())
31            }
32            Entry::Occupied(mut entry) => {
33                let existing = entry.get();
34
35                prompt_handler
36                    .handle_channel_duplication(ChannelDuplication::SpeedFactorChangeEvent {
37                        time: speed_factor_change.time,
38                        older: existing,
39                        newer: &speed_factor_change,
40                    })
41                    .apply_channel(
42                        entry.get_mut(),
43                        speed_factor_change.clone(),
44                        speed_factor_change.time,
45                        Channel::Speed,
46                    )
47            }
48        }
49    }
50}