1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! This module introduces struct [`Video`], which manages configuration of playing background movie.
use std::{
collections::{BTreeMap, HashMap},
path::PathBuf,
};
use strict_num_extended::FinF64;
use crate::bms::{command::StringValue, parse::Result, prelude::*};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
/// This aggregate manages configuration of playing background movie.
pub struct Video {
/// Movie Define. Defines the global video file for the chart.
/// - Video starts from section #000
/// - Priority rules apply when conflicting with #xxx04
/// - No loop, stays on last frame after playback
/// - Audio track in video is not played
pub video_file: Option<PathBuf>,
/// Video color depth. `#VIDEOCOLORS`
pub video_colors: Option<u8>,
/// Video delay. `#VIDEODLY`
pub video_dly: Option<StringValue<FinF64>>,
/// Video frame rate. `#VIDEOF/S`
pub video_fs: Option<StringValue<FinF64>>,
/// Seek event definitions. `#SEEK`
pub seek_defs: HashMap<ObjId, StringValue<FinF64>>,
/// Seek events, indexed by time. `#xxx05:`
pub seek_events: BTreeMap<ObjTime, SeekObj>,
}
impl Video {
/// Adds a new seek object to the notes.
///
/// # Errors
///
/// Returns [`ParseWarning`] if a conflict is found and the
/// provided [`Prompter`] decides to treat it as an error.
pub fn push_seek_event(
&mut self,
seek_obj: SeekObj,
prompt_handler: &impl Prompter,
) -> Result<()> {
use std::collections::btree_map::Entry;
match self.seek_events.entry(seek_obj.time) {
Entry::Vacant(entry) => {
entry.insert(seek_obj);
Ok(())
}
Entry::Occupied(mut entry) => {
use crate::bms::parse::prompt::ChannelDuplication;
let existing = entry.get();
prompt_handler
.handle_channel_duplication(ChannelDuplication::SeekMessageEvent {
time: seek_obj.time,
older: existing,
newer: &seek_obj,
})
.apply_channel(
entry.get_mut(),
seek_obj.clone(),
seek_obj.time,
Channel::Seek,
)
}
}
}
}