mirror of
https://github.com/rust-mobile/android-activity.git
synced 2026-07-04 05:47:26 +00:00
Runs cargo fmt across everything
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
use log::Level;
|
||||
use winit::event_loop::{EventLoopWindowTarget, EventLoopBuilder, EventLoop};
|
||||
use winit::event_loop::{EventLoop, EventLoopBuilder, EventLoopWindowTarget};
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
use android_activity::AndroidApp;
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
use winit::platform::android::EventLoopBuilderExtAndroid;
|
||||
|
||||
use winit::{
|
||||
event_loop::{ControlFlow},
|
||||
};
|
||||
use winit::event_loop::ControlFlow;
|
||||
|
||||
use egui_wgpu::winit::Painter;
|
||||
use egui_winit::State;
|
||||
@@ -26,8 +24,11 @@ enum Event {
|
||||
#[derive(Clone)]
|
||||
struct RepaintSignal(std::sync::Arc<std::sync::Mutex<winit::event_loop::EventLoopProxy<Event>>>);
|
||||
|
||||
|
||||
fn create_window<T>(event_loop: &EventLoopWindowTarget<T>, state: &mut State, painter: &mut Painter) -> winit::window::Window {
|
||||
fn create_window<T>(
|
||||
event_loop: &EventLoopWindowTarget<T>,
|
||||
state: &mut State,
|
||||
painter: &mut Painter,
|
||||
) -> winit::window::Window {
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_decorations(true)
|
||||
.with_resizable(true)
|
||||
@@ -37,8 +38,8 @@ fn create_window<T>(event_loop: &EventLoopWindowTarget<T>, state: &mut State, pa
|
||||
width: INITIAL_WIDTH,
|
||||
height: INITIAL_HEIGHT,
|
||||
})
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
unsafe { painter.set_window(Some(&window)) };
|
||||
|
||||
@@ -60,10 +61,15 @@ fn create_window<T>(event_loop: &EventLoopWindowTarget<T>, state: &mut State, pa
|
||||
fn _main(event_loop: EventLoop<Event>) {
|
||||
let ctx = egui::Context::default();
|
||||
let repaint_signal = RepaintSignal(std::sync::Arc::new(std::sync::Mutex::new(
|
||||
event_loop.create_proxy()
|
||||
event_loop.create_proxy(),
|
||||
)));
|
||||
ctx.set_request_repaint_callback(move || {
|
||||
repaint_signal.0.lock().unwrap().send_event(Event::RequestRedraw).ok();
|
||||
repaint_signal
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send_event(Event::RequestRedraw)
|
||||
.ok();
|
||||
});
|
||||
|
||||
let mut state = State::new(&event_loop);
|
||||
@@ -73,90 +79,85 @@ fn _main(event_loop: EventLoop<Event>) {
|
||||
wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
features: wgpu::Features::default(),
|
||||
limits: wgpu::Limits::default()
|
||||
limits: wgpu::Limits::default(),
|
||||
},
|
||||
wgpu::PresentMode::Fifo,
|
||||
1);
|
||||
1,
|
||||
);
|
||||
let mut window: Option<winit::window::Window> = None;
|
||||
let mut egui_demo_windows = egui_demo_lib::DemoWindows::default();
|
||||
|
||||
// On most platforms we can immediately create a winit window. On Android we manage
|
||||
// window + surface state according to Resumed/Paused events.
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
window = Some(create_window(&event_loop, &mut state, &mut painter));
|
||||
}
|
||||
|
||||
event_loop.run(move |event, event_loop, control_flow| {
|
||||
|
||||
match event {
|
||||
#[cfg(target_os="android")]
|
||||
Resumed => {
|
||||
match window {
|
||||
None => {
|
||||
window = Some(create_window(event_loop, &mut state, &mut painter));
|
||||
}
|
||||
Some(ref window) => {
|
||||
unsafe { painter.set_window(Some(window)) };
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
event_loop.run(move |event, event_loop, control_flow| match event {
|
||||
#[cfg(target_os = "android")]
|
||||
Resumed => match window {
|
||||
None => {
|
||||
window = Some(create_window(event_loop, &mut state, &mut painter));
|
||||
}
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
Suspended => {
|
||||
window = None;
|
||||
Some(ref window) => {
|
||||
unsafe { painter.set_window(Some(window)) };
|
||||
window.request_redraw();
|
||||
}
|
||||
},
|
||||
|
||||
RedrawRequested(..) => {
|
||||
if let Some(window) = window.as_ref() {
|
||||
let raw_input = state.take_egui_input(window);
|
||||
#[cfg(target_os = "android")]
|
||||
Suspended => {
|
||||
window = None;
|
||||
}
|
||||
|
||||
let full_output = ctx.run(raw_input, |ctx| {
|
||||
egui_demo_windows.ui(ctx);
|
||||
});
|
||||
state.handle_platform_output(window, &ctx, full_output.platform_output);
|
||||
RedrawRequested(..) => {
|
||||
if let Some(window) = window.as_ref() {
|
||||
let raw_input = state.take_egui_input(window);
|
||||
|
||||
painter.paint_and_update_textures(state.pixels_per_point(),
|
||||
egui::Rgba::default(),
|
||||
&ctx.tessellate(full_output.shapes),
|
||||
&full_output.textures_delta);
|
||||
let full_output = ctx.run(raw_input, |ctx| {
|
||||
egui_demo_windows.ui(ctx);
|
||||
});
|
||||
state.handle_platform_output(window, &ctx, full_output.platform_output);
|
||||
|
||||
if full_output.repaint_after.is_zero() {
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
MainEventsCleared | UserEvent(Event::RequestRedraw) => {
|
||||
if let Some(window) = window.as_ref() {
|
||||
painter.paint_and_update_textures(
|
||||
state.pixels_per_point(),
|
||||
egui::Rgba::default(),
|
||||
&ctx.tessellate(full_output.shapes),
|
||||
&full_output.textures_delta,
|
||||
);
|
||||
|
||||
if full_output.repaint_after.is_zero() {
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
WindowEvent { event, .. } => {
|
||||
if state.on_event(&ctx, &event) == false {
|
||||
match event {
|
||||
winit::event::WindowEvent::Resized(size) => {
|
||||
painter.on_window_resized(size.width, size.height);
|
||||
}
|
||||
winit::event::WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
MainEventsCleared | UserEvent(Event::RequestRedraw) => {
|
||||
if let Some(window) = window.as_ref() {
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
WindowEvent { event, .. } => {
|
||||
if state.on_event(&ctx, &event) == false {
|
||||
match event {
|
||||
winit::event::WindowEvent::Resized(size) => {
|
||||
painter.on_window_resized(size.width, size.height);
|
||||
}
|
||||
winit::event::WindowEvent::CloseRequested => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(Level::Trace)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(Level::Trace));
|
||||
|
||||
let event_loop = EventLoopBuilder::with_user_event()
|
||||
.with_android_app(app)
|
||||
@@ -164,12 +165,13 @@ fn android_main(app: AndroidApp) {
|
||||
_main(event_loop);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn main() {
|
||||
env_logger::builder().filter_level(log::LevelFilter::Warn) // Default Log Level
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Warn) // Default Log Level
|
||||
.parse_default_env()
|
||||
.init();
|
||||
|
||||
let event_loop = EventLoopBuilder::with_user_event().build();
|
||||
_main(event_loop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,76 @@
|
||||
use android_activity::{AndroidApp, PollEvent, MainEvent};
|
||||
use android_activity::{AndroidApp, MainEvent, PollEvent};
|
||||
use log::info;
|
||||
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(log::Level::Info)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Info));
|
||||
|
||||
let mut quit = false;
|
||||
let mut redraw_pending = true;
|
||||
let mut render_state: Option<()> = Default::default();
|
||||
|
||||
while !quit {
|
||||
app.poll_events(Some(std::time::Duration::from_millis(500)) /* timeout */, |event| {
|
||||
match event {
|
||||
PollEvent::Wake => { info!("Early wake up"); },
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
},
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
},
|
||||
MainEvent::Pause => {},
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
app.poll_events(
|
||||
Some(std::time::Duration::from_millis(500)), /* timeout */
|
||||
|event| {
|
||||
match event {
|
||||
PollEvent::Wake => {
|
||||
info!("Early wake up");
|
||||
}
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
}
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
}
|
||||
MainEvent::Pause => {}
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
},
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::RedrawNeeded { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::LowMemory => {}
|
||||
|
||||
MainEvent::Destroy => quit = true,
|
||||
_ => { /* ... */ }
|
||||
}
|
||||
MainEvent::WindowResized { .. } => { redraw_pending = true; },
|
||||
MainEvent::RedrawNeeded { ..} => { redraw_pending = true; },
|
||||
MainEvent::LowMemory => {},
|
||||
|
||||
MainEvent::Destroy => { quit = true },
|
||||
_ => { /* ... */}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,4 +217,4 @@ pub fn audio_probe() {
|
||||
println!(" Formats: {:?}", device.formats);
|
||||
println!("}}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use android_activity::{AndroidApp, PollEvent, MainEvent};
|
||||
use android_activity::{AndroidApp, MainEvent, PollEvent};
|
||||
use log::info;
|
||||
|
||||
mod audio;
|
||||
@@ -6,9 +6,7 @@ use audio::*;
|
||||
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(log::Level::Info)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Info));
|
||||
|
||||
let mut quit = false;
|
||||
let mut redraw_pending = true;
|
||||
@@ -17,64 +15,72 @@ fn android_main(app: AndroidApp) {
|
||||
let mut sine = SineGen::default();
|
||||
|
||||
while !quit {
|
||||
app.poll_events(Some(std::time::Duration::from_millis(500)) /* timeout */, |event| {
|
||||
match event {
|
||||
PollEvent::Wake => { info!("Early wake up"); },
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
},
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
},
|
||||
MainEvent::Pause => {
|
||||
sine.try_stop();
|
||||
},
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
audio_probe();
|
||||
sine.try_start();
|
||||
},
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
},
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => { redraw_pending = true; },
|
||||
MainEvent::RedrawNeeded { ..} => { redraw_pending = true; },
|
||||
MainEvent::LowMemory => {},
|
||||
|
||||
MainEvent::Destroy => { quit = true },
|
||||
_ => { /* ... */}
|
||||
app.poll_events(
|
||||
Some(std::time::Duration::from_millis(500)), /* timeout */
|
||||
|event| {
|
||||
match event {
|
||||
PollEvent::Wake => {
|
||||
info!("Early wake up");
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
}
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
}
|
||||
MainEvent::Pause => {
|
||||
sine.try_stop();
|
||||
}
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
audio_probe();
|
||||
sine.try_start();
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::RedrawNeeded { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::LowMemory => {}
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
MainEvent::Destroy => quit = true,
|
||||
_ => { /* ... */ }
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::borrow::Cow;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use log::Level;
|
||||
use log::trace;
|
||||
use log::Level;
|
||||
|
||||
use wgpu::TextureFormat;
|
||||
use wgpu::{Instance, Adapter, Device, ShaderModule, PipelineLayout, RenderPipeline, Queue};
|
||||
use wgpu::{Adapter, Device, Instance, PipelineLayout, Queue, RenderPipeline, ShaderModule};
|
||||
|
||||
use winit::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopWindowTarget},
|
||||
};
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
use android_activity::AndroidApp;
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
use winit::platform::android::EventLoopBuilderExtAndroid;
|
||||
|
||||
struct RenderState {
|
||||
@@ -30,7 +29,7 @@ struct RenderState {
|
||||
|
||||
struct SurfaceState {
|
||||
window: winit::window::Window,
|
||||
surface: wgpu::Surface
|
||||
surface: wgpu::Surface,
|
||||
}
|
||||
|
||||
struct AppInner {
|
||||
@@ -41,7 +40,7 @@ struct AppInner {
|
||||
}
|
||||
|
||||
struct App {
|
||||
inner: Arc<RwLock<AppInner>>
|
||||
inner: Arc<RwLock<AppInner>>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@@ -52,7 +51,7 @@ impl App {
|
||||
adapter: None,
|
||||
surface_state: None,
|
||||
render_state: None,
|
||||
}))
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +62,6 @@ impl Deref for App {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn init_render_state(adapter: &Adapter, target_format: TextureFormat) -> RenderState {
|
||||
trace!("Initializing render state");
|
||||
|
||||
@@ -141,7 +139,9 @@ fn configure_surface_swapchain(render_state: &RenderState, surface_state: &Surfa
|
||||
};
|
||||
|
||||
trace!("WGPU: Configuring surface swapchain: format = {swapchain_format:?}, size = {size:?}");
|
||||
surface_state.surface.configure(&render_state.device, &config);
|
||||
surface_state
|
||||
.surface
|
||||
.configure(&render_state.device, &config);
|
||||
}
|
||||
|
||||
// We want to defer the initialization of our render state until
|
||||
@@ -155,7 +155,8 @@ async fn ensure_render_state_for_surface(app: &App, new_surface_state: &SurfaceS
|
||||
|
||||
if app_guard.adapter.is_none() {
|
||||
trace!("WGPU: requesting a suitable adapter (compatible with our surface)");
|
||||
let adapter = app_guard.instance
|
||||
let adapter = app_guard
|
||||
.instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
force_fallback_adapter: false,
|
||||
@@ -185,10 +186,7 @@ fn create_surface<T>(app: &App, event_loop: &EventLoopWindowTarget<T>) -> Surfac
|
||||
let guard = app.inner.read().unwrap();
|
||||
let surface = unsafe { guard.instance.create_surface(&window) };
|
||||
|
||||
SurfaceState {
|
||||
window,
|
||||
surface
|
||||
}
|
||||
SurfaceState { window, surface }
|
||||
}
|
||||
|
||||
fn resume<T>(app: &App, event_loop: &EventLoopWindowTarget<T>) {
|
||||
@@ -209,9 +207,7 @@ fn resume<T>(app: &App, event_loop: &EventLoopWindowTarget<T>) {
|
||||
surface_state.window.request_redraw();
|
||||
}
|
||||
|
||||
|
||||
fn run(event_loop: EventLoop<()>, app: App) {
|
||||
|
||||
//let mut running = false;
|
||||
|
||||
trace!("Running mainloop...");
|
||||
@@ -225,7 +221,7 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
// Note: that because Winit doesn't currently support lifecycle events consistently
|
||||
// across platforms then we effectively issue a fake 'resume' on non-android
|
||||
// platforms...
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
resume(&app, event_loop)
|
||||
}
|
||||
Event::Resumed => {
|
||||
@@ -236,7 +232,7 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
let mut guard = app.write().unwrap();
|
||||
//guard.running = false;
|
||||
guard.render_state = None;
|
||||
},
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::Resized(_size),
|
||||
..
|
||||
@@ -258,27 +254,32 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
let guard = app.read().unwrap();
|
||||
if let Some(ref surface_state) = guard.surface_state {
|
||||
if let Some(ref rs) = guard.render_state {
|
||||
let frame = surface_state.surface
|
||||
let frame = surface_state
|
||||
.surface
|
||||
.get_current_texture()
|
||||
.expect("Failed to acquire next swap chain texture");
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder =
|
||||
rs.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
rs.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: None,
|
||||
});
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: true,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
let mut rpass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: true,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&rs.render_pipeline);
|
||||
rpass.draw(0..3, 0..1);
|
||||
}
|
||||
@@ -298,7 +299,6 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
fn _main(event_loop: EventLoop<()>) {
|
||||
// We can decide on our graphics API / backend up-front and that
|
||||
// doesn't need to be re-considered later
|
||||
@@ -311,26 +311,22 @@ fn _main(event_loop: EventLoop<()>) {
|
||||
run(event_loop, app);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(Level::Trace)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(Level::Trace));
|
||||
|
||||
let event_loop = EventLoopBuilder::new()
|
||||
.with_android_app(app)
|
||||
.build();
|
||||
let event_loop = EventLoopBuilder::new().with_android_app(app).build();
|
||||
_main(event_loop);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn main() {
|
||||
env_logger::builder().filter_level(log::LevelFilter::Warn) // Default Log Level
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Warn) // Default Log Level
|
||||
.parse_default_env()
|
||||
.init();
|
||||
|
||||
let event_loop = EventLoopBuilder::new().build();
|
||||
_main(event_loop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,76 @@
|
||||
use android_activity::{PollEvent, MainEvent, AndroidApp};
|
||||
use android_activity::{AndroidApp, MainEvent, PollEvent};
|
||||
use log::info;
|
||||
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(log::Level::Info)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Info));
|
||||
|
||||
let mut quit = false;
|
||||
let mut redraw_pending = true;
|
||||
let mut render_state: Option<()> = Default::default();
|
||||
|
||||
while !quit {
|
||||
app.poll_events(Some(std::time::Duration::from_millis(500)) /* timeout */, |event| {
|
||||
match event {
|
||||
PollEvent::Wake => { info!("Early wake up"); },
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
},
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
},
|
||||
MainEvent::Pause => {},
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
app.poll_events(
|
||||
Some(std::time::Duration::from_millis(500)), /* timeout */
|
||||
|event| {
|
||||
match event {
|
||||
PollEvent::Wake => {
|
||||
info!("Early wake up");
|
||||
}
|
||||
PollEvent::Timeout => {
|
||||
info!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
}
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
saver.store("foo://bar".as_bytes());
|
||||
}
|
||||
MainEvent::Pause => {}
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
if let Ok(uri) = String::from_utf8(state) {
|
||||
info!("Resumed with saved state = {uri:#?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
},
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::RedrawNeeded { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::LowMemory => {}
|
||||
|
||||
MainEvent::Destroy => quit = true,
|
||||
_ => { /* ... */ }
|
||||
}
|
||||
MainEvent::WindowResized { .. } => { redraw_pending = true; },
|
||||
MainEvent::RedrawNeeded { ..} => { redraw_pending = true; },
|
||||
MainEvent::LowMemory => {},
|
||||
|
||||
MainEvent::Destroy => { quit = true },
|
||||
_ => { /* ... */}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if redraw_pending {
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
});
|
||||
|
||||
info!("Render...");
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
|
||||
use android_activity::{PollEvent, MainEvent, AndroidApp};
|
||||
use android_activity::{AndroidApp, MainEvent, PollEvent};
|
||||
use log::Level;
|
||||
use log::{trace, info};
|
||||
use log::{info, trace};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct AppState {
|
||||
@@ -12,77 +11,85 @@ struct AppState {
|
||||
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(Level::Info)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(Level::Info));
|
||||
|
||||
let mut quit = false;
|
||||
let mut redraw_pending = true;
|
||||
let mut render_state: Option<()> = Default::default();
|
||||
|
||||
while !quit {
|
||||
app.poll_events(Some(Duration::from_millis(500)) /* timeout */, |event| {
|
||||
match event {
|
||||
PollEvent::Wake => { trace!("Early wake up"); },
|
||||
PollEvent::Timeout => {
|
||||
trace!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
},
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
let state = serde_json::to_vec(&AppState { uri: format!("foo://bar") }).unwrap();
|
||||
saver.store(&state);
|
||||
},
|
||||
MainEvent::Pause => {},
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
let state: AppState = serde_json::from_slice(&state).unwrap();
|
||||
info!("Resumed with saved state = {state:#?}");
|
||||
}
|
||||
},
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
},
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => { redraw_pending = true; },
|
||||
MainEvent::RedrawNeeded { ..} => { redraw_pending = true; },
|
||||
MainEvent::LowMemory => {},
|
||||
|
||||
MainEvent::Destroy => { quit = true },
|
||||
_ => { /* ... */}
|
||||
app.poll_events(
|
||||
Some(Duration::from_millis(500)), /* timeout */
|
||||
|event| {
|
||||
match event {
|
||||
PollEvent::Wake => {
|
||||
trace!("Early wake up");
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
PollEvent::Timeout => {
|
||||
trace!("Timed out");
|
||||
// Real app would probably rely on vblank sync via graphics API...
|
||||
redraw_pending = true;
|
||||
}
|
||||
PollEvent::Main(main_event) => {
|
||||
info!("Main event: {:?}", main_event);
|
||||
match main_event {
|
||||
MainEvent::SaveState { saver, .. } => {
|
||||
let state = serde_json::to_vec(&AppState {
|
||||
uri: format!("foo://bar"),
|
||||
})
|
||||
.unwrap();
|
||||
saver.store(&state);
|
||||
}
|
||||
MainEvent::Pause => {}
|
||||
MainEvent::Resume { loader, .. } => {
|
||||
if let Some(state) = loader.load() {
|
||||
let state: AppState = serde_json::from_slice(&state).unwrap();
|
||||
info!("Resumed with saved state = {state:#?}");
|
||||
}
|
||||
}
|
||||
MainEvent::InitWindow { .. } => {
|
||||
render_state = Some(());
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::TerminateWindow { .. } => {
|
||||
render_state = None;
|
||||
}
|
||||
MainEvent::WindowResized { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::RedrawNeeded { .. } => {
|
||||
redraw_pending = true;
|
||||
}
|
||||
MainEvent::LowMemory => {}
|
||||
|
||||
if redraw_pending {
|
||||
info!("Checking input: START");
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
|
||||
});
|
||||
|
||||
// Render...
|
||||
MainEvent::Destroy => quit = true,
|
||||
_ => { /* ... */ }
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
info!("Checking input: DONE");
|
||||
} else {
|
||||
info!("No redraw pending");
|
||||
}
|
||||
});
|
||||
|
||||
if redraw_pending {
|
||||
info!("Checking input: START");
|
||||
if let Some(_rs) = render_state {
|
||||
redraw_pending = false;
|
||||
|
||||
// Handle input
|
||||
app.input_events(|event| {
|
||||
info!("Input Event: {event:?}");
|
||||
});
|
||||
|
||||
// Render...
|
||||
}
|
||||
info!("Checking input: DONE");
|
||||
} else {
|
||||
info!("No redraw pending");
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Java_co_realfit_nasubclassjni_MainActivity_notifyOnNewIntent(
|
||||
@@ -91,4 +98,4 @@ pub extern "C" fn Java_co_realfit_nasubclassjni_MainActivity_notifyOnNewIntent(
|
||||
_activity: jni::objects::JObject,
|
||||
) {
|
||||
info!("onNewIntent was called!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::borrow::Cow;
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use log::Level;
|
||||
use log::trace;
|
||||
use log::Level;
|
||||
|
||||
use wgpu::TextureFormat;
|
||||
use wgpu::{Instance, Adapter, Device, ShaderModule, PipelineLayout, RenderPipeline, Queue};
|
||||
use wgpu::{Adapter, Device, Instance, PipelineLayout, Queue, RenderPipeline, ShaderModule};
|
||||
|
||||
use winit::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget, EventLoopBuilder},
|
||||
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopWindowTarget},
|
||||
};
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
use android_activity::AndroidApp;
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
use winit::platform::android::EventLoopBuilderExtAndroid;
|
||||
|
||||
struct RenderState {
|
||||
@@ -30,7 +29,7 @@ struct RenderState {
|
||||
|
||||
struct SurfaceState {
|
||||
window: winit::window::Window,
|
||||
surface: wgpu::Surface
|
||||
surface: wgpu::Surface,
|
||||
}
|
||||
|
||||
struct AppInner {
|
||||
@@ -41,7 +40,7 @@ struct AppInner {
|
||||
}
|
||||
|
||||
struct App {
|
||||
inner: Arc<RwLock<AppInner>>
|
||||
inner: Arc<RwLock<AppInner>>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@@ -52,7 +51,7 @@ impl App {
|
||||
adapter: None,
|
||||
surface_state: None,
|
||||
render_state: None,
|
||||
}))
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +62,6 @@ impl Deref for App {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn init_render_state(adapter: &Adapter, target_format: TextureFormat) -> RenderState {
|
||||
trace!("Initializing render state");
|
||||
|
||||
@@ -141,7 +139,9 @@ fn configure_surface_swapchain(render_state: &RenderState, surface_state: &Surfa
|
||||
};
|
||||
|
||||
trace!("WGPU: Configuring surface swapchain: format = {swapchain_format:?}, size = {size:?}");
|
||||
surface_state.surface.configure(&render_state.device, &config);
|
||||
surface_state
|
||||
.surface
|
||||
.configure(&render_state.device, &config);
|
||||
}
|
||||
|
||||
// We want to defer the initialization of our render state until
|
||||
@@ -155,7 +155,8 @@ async fn ensure_render_state_for_surface(app: &App, new_surface_state: &SurfaceS
|
||||
|
||||
if app_guard.adapter.is_none() {
|
||||
trace!("WGPU: requesting a suitable adapter (compatible with our surface)");
|
||||
let adapter = app_guard.instance
|
||||
let adapter = app_guard
|
||||
.instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
power_preference: wgpu::PowerPreference::default(),
|
||||
force_fallback_adapter: false,
|
||||
@@ -171,7 +172,10 @@ async fn ensure_render_state_for_surface(app: &App, new_surface_state: &SurfaceS
|
||||
|
||||
if app_guard.render_state.is_none() {
|
||||
trace!("WGPU: finding preferred swapchain format");
|
||||
let swapchain_format = new_surface_state.surface.get_preferred_format(&adapter).unwrap();
|
||||
let swapchain_format = new_surface_state
|
||||
.surface
|
||||
.get_preferred_format(&adapter)
|
||||
.unwrap();
|
||||
|
||||
let rs = init_render_state(adapter, swapchain_format).await;
|
||||
app_guard.render_state = Some(rs);
|
||||
@@ -185,10 +189,7 @@ fn create_surface<T>(app: &App, event_loop: &EventLoopWindowTarget<T>) -> Surfac
|
||||
let guard = app.inner.read().unwrap();
|
||||
let surface = unsafe { guard.instance.create_surface(&window) };
|
||||
|
||||
SurfaceState {
|
||||
window,
|
||||
surface
|
||||
}
|
||||
SurfaceState { window, surface }
|
||||
}
|
||||
|
||||
fn resume<T>(app: &App, event_loop: &EventLoopWindowTarget<T>) {
|
||||
@@ -209,9 +210,7 @@ fn resume<T>(app: &App, event_loop: &EventLoopWindowTarget<T>) {
|
||||
surface_state.window.request_redraw();
|
||||
}
|
||||
|
||||
|
||||
fn run(event_loop: EventLoop<()>, app: App) {
|
||||
|
||||
//let mut running = false;
|
||||
|
||||
trace!("Running mainloop...");
|
||||
@@ -225,7 +224,7 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
// Note: that because Winit doesn't currently support lifecycle events consistently
|
||||
// across platforms then we effectively issue a fake 'resume' on non-android
|
||||
// platforms...
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
resume(&app, event_loop)
|
||||
}
|
||||
Event::Resumed => {
|
||||
@@ -236,7 +235,7 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
let mut guard = app.write().unwrap();
|
||||
//guard.running = false;
|
||||
guard.render_state = None;
|
||||
},
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::Resized(_size),
|
||||
..
|
||||
@@ -258,27 +257,32 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
let guard = app.read().unwrap();
|
||||
if let Some(ref surface_state) = guard.surface_state {
|
||||
if let Some(ref rs) = guard.render_state {
|
||||
let frame = surface_state.surface
|
||||
let frame = surface_state
|
||||
.surface
|
||||
.get_current_texture()
|
||||
.expect("Failed to acquire next swap chain texture");
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
let mut encoder =
|
||||
rs.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
rs.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: None,
|
||||
});
|
||||
{
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
let mut rpass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: None,
|
||||
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||
view: &view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
rpass.set_pipeline(&rs.render_pipeline);
|
||||
rpass.draw(0..3, 0..1);
|
||||
}
|
||||
@@ -298,7 +302,6 @@ fn run(event_loop: EventLoop<()>, app: App) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
fn _main(event_loop: EventLoop<()>) {
|
||||
// We can decide on our graphics API / backend up-front and that
|
||||
// doesn't need to be re-considered later
|
||||
@@ -311,26 +314,22 @@ fn _main(event_loop: EventLoop<()>) {
|
||||
run(event_loop, app);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
#[cfg(target_os = "android")]
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default().with_min_level(Level::Trace)
|
||||
);
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(Level::Trace));
|
||||
|
||||
let event_loop = EventLoopBuilder::new()
|
||||
.with_android_app(app)
|
||||
.build();
|
||||
let event_loop = EventLoopBuilder::new().with_android_app(app).build();
|
||||
_main(event_loop);
|
||||
}
|
||||
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn main() {
|
||||
env_logger::builder().filter_level(log::LevelFilter::Warn) // Default Log Level
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Warn) // Default Log Level
|
||||
.parse_default_env()
|
||||
.init();
|
||||
|
||||
let event_loop = EventLoopBuilder::new().build();
|
||||
_main(event_loop);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user