1use bevy::{
7 prelude::*,
8 window::{PresentMode, RequestRedraw, WindowPlugin},
9 winit::{EventLoopProxyWrapper, WakeUp, WinitSettings},
10};
11use core::time::Duration;
12
13fn main() {
14 App::new()
15 .insert_resource(WinitSettings::game())
17 .insert_resource(WinitSettings::desktop_app())
19 .insert_resource(WinitSettings {
21 focused_mode: bevy::winit::UpdateMode::Continuous,
22 unfocused_mode: bevy::winit::UpdateMode::reactive_low_power(Duration::from_millis(10)),
23 })
24 .insert_resource(ExampleMode::Game)
25 .add_plugins(DefaultPlugins.set(WindowPlugin {
26 primary_window: Some(Window {
27 present_mode: PresentMode::AutoNoVsync,
29 ..default()
30 }),
31 ..default()
32 }))
33 .add_systems(Startup, test_setup::setup)
34 .add_systems(
35 Update,
36 (
37 test_setup::cycle_modes,
38 test_setup::rotate_cube,
39 test_setup::update_text,
40 update_winit,
41 ),
42 )
43 .run();
44}
45
46#[derive(Resource, Debug)]
47enum ExampleMode {
48 Game,
49 Application,
50 ApplicationWithRequestRedraw,
51 ApplicationWithWakeUp,
52}
53
54fn update_winit(
56 mode: Res<ExampleMode>,
57 mut winit_config: ResMut<WinitSettings>,
58 event_loop_proxy: Res<EventLoopProxyWrapper<WakeUp>>,
59 mut redraw_request_writer: MessageWriter<RequestRedraw>,
60) {
61 use ExampleMode::*;
62 *winit_config = match *mode {
63 Game => {
64 WinitSettings::game()
71 }
72 Application => {
73 WinitSettings::desktop_app()
82 }
83 ApplicationWithRequestRedraw => {
84 redraw_request_writer.write(RequestRedraw);
91 WinitSettings::desktop_app()
92 }
93 ApplicationWithWakeUp => {
94 let _ = event_loop_proxy.send_event(WakeUp);
100 WinitSettings::desktop_app()
101 }
102 };
103}
104
105pub(crate) mod test_setup {
108 use crate::ExampleMode;
109 use bevy::{
110 color::palettes::basic::{LIME, YELLOW},
111 prelude::*,
112 window::RequestRedraw,
113 };
114
115 pub(crate) fn cycle_modes(
117 mut mode: ResMut<ExampleMode>,
118 button_input: Res<ButtonInput<KeyCode>>,
119 ) {
120 if button_input.just_pressed(KeyCode::Space) {
121 *mode = match *mode {
122 ExampleMode::Game => ExampleMode::Application,
123 ExampleMode::Application => ExampleMode::ApplicationWithRequestRedraw,
124 ExampleMode::ApplicationWithRequestRedraw => ExampleMode::ApplicationWithWakeUp,
125 ExampleMode::ApplicationWithWakeUp => ExampleMode::Game,
126 };
127 }
128 }
129
130 #[derive(Component)]
131 pub(crate) struct Rotator;
132
133 pub(crate) fn rotate_cube(
135 time: Res<Time>,
136 mut cube_transform: Query<&mut Transform, With<Rotator>>,
137 ) {
138 for mut transform in &mut cube_transform {
139 transform.rotate_x(time.delta_secs());
140 transform.rotate_local_y(time.delta_secs());
141 }
142 }
143
144 #[derive(Component)]
145 pub struct ModeText;
146
147 pub(crate) fn update_text(
148 mut frame: Local<usize>,
149 mode: Res<ExampleMode>,
150 text: Single<Entity, With<ModeText>>,
151 mut writer: TextUiWriter,
152 ) {
153 *frame += 1;
154 let mode = match *mode {
155 ExampleMode::Game => "game(), continuous, default",
156 ExampleMode::Application => "desktop_app(), reactive",
157 ExampleMode::ApplicationWithRequestRedraw => {
158 "desktop_app(), reactive, RequestRedraw sent"
159 }
160 ExampleMode::ApplicationWithWakeUp => "desktop_app(), reactive, WakeUp sent",
161 };
162 *writer.text(*text, 2) = mode.to_string();
163 *writer.text(*text, 4) = frame.to_string();
164 }
165
166 pub fn setup(
168 mut commands: Commands,
169 mut meshes: ResMut<Assets<Mesh>>,
170 mut materials: ResMut<Assets<StandardMaterial>>,
171 mut request_redraw_writer: MessageWriter<RequestRedraw>,
172 ) {
173 commands.spawn((
174 Mesh3d(meshes.add(Cuboid::new(0.5, 0.5, 0.5))),
175 MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
176 Rotator,
177 ));
178
179 commands.spawn((
180 DirectionalLight::default(),
181 Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
182 ));
183 commands.spawn((
184 Camera3d::default(),
185 Transform::from_xyz(-2.0, 2.0, 2.0).looking_at(Vec3::ZERO, Vec3::Y),
186 ));
187 request_redraw_writer.write(RequestRedraw);
188 commands.spawn((
189 Text::default(),
190 Node {
191 align_self: AlignSelf::FlexStart,
192 position_type: PositionType::Absolute,
193 top: px(12),
194 left: px(12),
195 ..default()
196 },
197 ModeText,
198 children![
199 TextSpan::new("Press space bar to cycle modes\n"),
200 (TextSpan::default(), TextColor(LIME.into())),
201 (TextSpan::new("\nFrame: "), TextColor(YELLOW.into())),
202 (TextSpan::new(""), TextColor(YELLOW.into())),
203 ],
204 ));
205 }
206}