1use std::marker::PhantomData;
2use std::time::Duration;
3
4use super::config::Config;
5use super::context::Context;
6use super::Constructor;
7
8#[derive(Default)]
10pub struct Builder<Cfg> {
11 _phantom: PhantomData<Cfg>,
12}
13
14impl<Cfg> Builder<Cfg>
15where
16 Cfg: Config,
17{
18 pub fn new() -> Builder<Cfg> {
20 Self {
21 _phantom: PhantomData,
22 }
23 }
24
25 pub fn with_render_target(self, render_target: Cfg::RenderTarget) -> StepRenderTarget<Cfg> {
27 StepRenderTarget { render_target }
28 }
29}
30
31pub struct StepRenderTarget<Cfg>
33where
34 Cfg: Config,
35{
36 render_target: Cfg::RenderTarget,
37}
38
39impl<Cfg> StepRenderTarget<Cfg>
40where
41 Cfg: Config,
42{
43 pub fn with_input(self, input: Cfg::Input) -> StepInput<Cfg> {
45 StepInput {
46 render_target: self.render_target,
47 input,
48 }
49 }
50}
51
52pub struct StepInput<Cfg>
54where
55 Cfg: Config,
56{
57 render_target: Cfg::RenderTarget,
58 input: Cfg::Input,
59}
60
61impl<Cfg> StepInput<Cfg>
62where
63 Cfg: Config,
64{
65 pub fn with_root_constructor<F>(self, constructor: F) -> Setup<Cfg>
67 where
68 F: 'static + FnOnce(&mut Context<Cfg>) -> Cfg::Root,
69 {
70 Setup::new(self.render_target, self.input, constructor)
71 }
72}
73
74pub struct Setup<Cfg>
77where
78 Cfg: Config,
79{
80 pub(super) title: String,
81 pub(super) update_delay: Duration,
82 pub(super) fullscreen: bool,
83 pub(super) scale: u32,
84 pub(super) render_target: Cfg::RenderTarget,
85 pub(super) constructor: Constructor<Cfg::Root, Cfg>,
86 #[cfg(target_arch = "wasm32")]
87 pub(super) element_id: Option<&'static str>,
88 pub(super) pause_on_focus_lost: bool,
89 pub(super) input: Cfg::Input,
90}
91
92impl<Cfg> Setup<Cfg>
93where
94 Cfg: Config,
95{
96 fn new<F>(render_target: Cfg::RenderTarget, input: Cfg::Input, constructor: F) -> Self
97 where
98 F: 'static + FnOnce(&mut Context<Cfg>) -> Cfg::Root,
99 {
100 let title = String::new();
101 let update_delay = Duration::from_secs_f64(1.0 / 30.0);
102 let fullscreen = false;
103 let scale = 1;
104 let constructor = Box::new(constructor);
105 Self {
106 title,
107 update_delay,
108 fullscreen,
109 scale,
110 render_target,
111 constructor,
112 #[cfg(target_arch = "wasm32")]
113 element_id: None,
114 pause_on_focus_lost: true,
115 input,
116 }
117 }
118
119 pub fn with_title<T: Into<String>>(self, title: T) -> Self {
121 Self {
122 title: title.into(),
123 ..self
124 }
125 }
126
127 pub fn with_scale(self, scale: u32) -> Self {
129 Self { scale, ..self }
130 }
131
132 pub fn with_fullscreen(self, fullscreen: bool) -> Self {
134 Self { fullscreen, ..self }
135 }
136
137 pub fn with_update_delay(self, update_delay: Duration) -> Self {
139 Self {
140 update_delay,
141 ..self
142 }
143 }
144
145 #[cfg(target_arch = "wasm32")]
146 pub fn with_element_id(self, element_id: &'static str) -> Self {
148 let element_id = Some(element_id);
149 Self { element_id, ..self }
150 }
151
152 pub fn with_pause_on_focus_lost(self, pause_on_focus_lost: bool) -> Self {
154 Self {
155 pause_on_focus_lost,
156 ..self
157 }
158 }
159}