1pub mod layout;
2
3use crate::layout::mania::{ManiaRenderer, NoteStyle};
4use rosu_map::section::general::GameMode;
5use rosu_map::Beatmap;
6use std::time::Instant;
7
8pub struct Player {
9 beatmap: Beatmap,
10 renderer: GameModeRenderer,
11 start_time: Instant,
12 speed: f64,
13 scroll_time_ms: f32,
14}
15
16enum GameModeRenderer {
17 Mania(ManiaRenderer),
18 }
23
24impl Player {
25 pub fn new(beatmap: Beatmap, column_width: f32, note_size: f32, height: f32) -> Option<Self> {
26 let renderer = match beatmap.mode {
28 GameMode::Mania => {
29 GameModeRenderer::Mania(ManiaRenderer::with_sizes(column_width, note_size, height))
30 }
31 _ => return None, };
37
38 Some(Self {
39 beatmap,
40 renderer,
41 start_time: Instant::now(),
42 speed: 1.0,
43 scroll_time_ms: 1000.0,
44 })
45 }
46
47 pub fn set_note_style(&mut self, style: NoteStyle) {
48 #[allow(irrefutable_let_patterns)]
49 if let GameModeRenderer::Mania(mania) = &mut self.renderer {
50 mania.set_note_style(style);
51 }
52 }
53
54 pub fn get_required_size(&self) -> [f32; 2] {
55 match &self.renderer {
56 GameModeRenderer::Mania(mania) => {
57 let keycount = self.beatmap.circle_size as usize;
58 [mania.required_width(keycount), mania.required_height()]
59 }
60 }
65 }
66
67 pub fn set_speed(&mut self, speed: f64) {
68 self.speed = speed;
69 }
70
71 pub fn set_scroll_time(&mut self, ms: f32) {
72 self.scroll_time_ms = ms;
73 }
74
75 pub fn render(&mut self, ui: &mut egui::Ui) {
76 self.render_at(ui, egui::pos2(0.0, 0.0))
77 }
78
79 pub fn render_at(&mut self, ui: &mut egui::Ui, position: egui::Pos2) {
80 let current_time = self.start_time.elapsed().as_secs_f64() * 1000.0;
81 let hit_objects = &self.beatmap.hit_objects;
82
83 match &mut self.renderer {
84 GameModeRenderer::Mania(mania) => {
85 let keycount = self.beatmap.circle_size as usize;
86 mania.render_at(
87 ui,
88 hit_objects,
89 current_time,
90 self.scroll_time_ms,
91 self.speed,
92 keycount,
93 position,
94 );
95 }
96 }
101 }
102
103 pub fn reset_time(&mut self) {
104 self.start_time = Instant::now();
105 }
106
107 pub fn set_current_time(&mut self, time_ms: f64) {
108 self.start_time = Instant::now() - std::time::Duration::from_secs_f64(time_ms / 1000.0);
109 }
110
111 pub fn current_time(&self) -> f64 {
112 self.start_time.elapsed().as_secs_f64() * 1000.0
113 }
114}