@@ -2,16 +2,13 @@ use futures::executor::{self, LocalPool, LocalSpawner};
2
2
use futures:: task:: LocalSpawn ;
3
3
use std:: cmp;
4
4
use std:: fmt:: Debug ;
5
- use wgpu :: { Device , Queue , SwapChainDescriptor , SwapChainTexture } ;
6
- use winit:: event:: { Event , WindowEvent } ;
7
- use winit:: event_loop:: { ControlFlow , EventLoop } ;
8
- use winit:: window:: Window ;
5
+ use winit :: application :: ApplicationHandler ;
6
+ use winit:: event:: WindowEvent ;
7
+ use winit:: event_loop:: { ActiveEventLoop , ControlFlow , EventLoop } ;
8
+ use winit:: window:: { Window , WindowId } ;
9
9
10
10
use crate :: renderer:: Renderer ;
11
11
12
- use ControlFlow :: Exit ;
13
- use ControlFlow :: Poll ;
14
-
15
12
struct Executor {
16
13
pool : LocalPool ,
17
14
spawner : LocalSpawner ,
@@ -41,17 +38,17 @@ pub enum Reaction {
41
38
}
42
39
43
40
pub trait ConfigureStage {
44
- fn device ( & self ) -> & Device ;
41
+ fn device ( & self ) -> & wgpu :: Device ;
45
42
46
- fn queue ( & self ) -> & Queue ;
43
+ fn queue ( & self ) -> & wgpu :: Queue ;
47
44
48
- fn swap_chain_descriptor ( & self ) -> & SwapChainDescriptor ;
45
+ fn surface_configuration ( & self ) -> & wgpu :: SurfaceConfiguration ;
49
46
}
50
47
51
48
pub trait RenderStage {
52
- fn device ( & self ) -> & Device ;
49
+ fn device ( & self ) -> & wgpu :: Device ;
53
50
54
- fn queue ( & self ) -> & Queue ;
51
+ fn queue ( & self ) -> & wgpu :: Queue ;
55
52
}
56
53
57
54
pub trait Application : ' static + Sized {
@@ -73,7 +70,7 @@ pub trait Application: 'static + Sized {
73
70
fn render (
74
71
& mut self ,
75
72
stage : & impl RenderStage ,
76
- frame : & SwapChainTexture ,
73
+ view : & wgpu :: TextureView ,
77
74
spawn : & impl LocalSpawn ,
78
75
) ;
79
76
}
@@ -83,48 +80,65 @@ where
83
80
T : Application ,
84
81
F : FnOnce ( & EventLoop < ( ) > ) -> Window ,
85
82
{
86
- let mut executor = Executor :: new ( ) ;
87
- let reactor = EventLoop :: new ( ) ;
88
- let mut renderer = executor :: block_on ( Renderer :: try_from_window ( f ( & reactor ) ) ) . unwrap ( ) ;
89
- let mut application = T :: configure ( configuration , & renderer ) . unwrap ( ) ;
90
- reactor . run ( move |event , _ , reaction| {
91
- * reaction = Poll ;
92
- match event {
93
- Event :: MainEventsCleared => {
94
- executor . flush ( ) ;
95
- }
96
- Event :: RedrawRequested ( _ ) => {
97
- let swap_chain = & mut renderer . swap_chain ;
98
- let frame = match swap_chain . get_current_frame ( ) {
99
- Ok ( frame ) => frame ,
100
- Err ( _ ) => {
101
- * swap_chain = renderer
102
- . device
103
- . create_swap_chain ( & renderer . surface , & renderer . swap_chain_descriptor ) ;
104
- swap_chain . get_current_frame ( ) . unwrap ( )
105
- }
106
- } ;
107
- application . render ( & renderer, & frame . output , executor. spawner ( ) ) ;
108
- }
109
- Event :: WindowEvent { event , .. } => match event {
83
+ struct Run < ' window , T > {
84
+ executor : Executor ,
85
+ application : T ,
86
+ window : & ' window Window ,
87
+ renderer : Renderer < ' window > ,
88
+ }
89
+
90
+ impl < ' window , T > ApplicationHandler < ( ) > for Run < ' window , T >
91
+ where
92
+ T : Application ,
93
+ {
94
+ fn resumed ( & mut self , _reactor : & ActiveEventLoop ) { }
95
+
96
+ fn window_event ( & mut self , reactor : & ActiveEventLoop , _ : WindowId , event : WindowEvent ) {
97
+ match event {
98
+ WindowEvent :: RedrawRequested => {
99
+ let frame = self . renderer . surface . get_current_texture ( ) . unwrap ( ) ;
100
+ let view = frame
101
+ . texture
102
+ . create_view ( & wgpu :: TextureViewDescriptor :: default ( ) ) ;
103
+ self . application
104
+ . render ( & self . renderer , & view , self . executor . spawner ( ) ) ;
105
+ frame . present ( ) ;
106
+ }
110
107
WindowEvent :: CloseRequested => {
111
- * reaction = Exit ;
108
+ reactor . exit ( ) ;
112
109
}
113
110
WindowEvent :: Resized ( dimensions) => {
114
- renderer. swap_chain_descriptor . width = cmp:: max ( 1 , dimensions. width ) ;
115
- renderer. swap_chain_descriptor . height = cmp:: max ( 1 , dimensions. height ) ;
116
- application. resize ( & renderer) ;
117
- renderer. swap_chain = renderer
118
- . device
119
- . create_swap_chain ( & renderer. surface , & renderer. swap_chain_descriptor ) ;
111
+ self . renderer . surface_configuration . width = cmp:: max ( 1 , dimensions. width ) ;
112
+ self . renderer . surface_configuration . height = cmp:: max ( 1 , dimensions. height ) ;
113
+ self . application . resize ( & self . renderer ) ;
114
+ self . renderer
115
+ . surface
116
+ . configure ( & self . renderer . device , & self . renderer . surface_configuration ) ;
117
+ self . window . request_redraw ( ) ;
120
118
}
121
119
_ => {
122
- if let Reaction :: Abort = application. react ( event) {
123
- * reaction = Exit ;
120
+ if let Reaction :: Abort = self . application . react ( event) {
121
+ reactor . exit ( ) ;
124
122
}
125
123
}
126
- } ,
127
- _ => { }
124
+ }
125
+ // TODO: This should probably be done in reaction to much more specific events.
126
+ self . executor . flush ( ) ;
128
127
}
129
- } ) ;
128
+ }
129
+
130
+ let executor = Executor :: new ( ) ;
131
+ let reactor = EventLoop :: new ( ) . unwrap ( ) ;
132
+ reactor. set_control_flow ( ControlFlow :: Poll ) ;
133
+ let window = f ( & reactor) ;
134
+ let renderer = executor:: block_on ( Renderer :: try_from_window ( & window) ) . unwrap ( ) ;
135
+ let application = T :: configure ( configuration, & renderer) . unwrap ( ) ;
136
+ reactor
137
+ . run_app ( & mut Run {
138
+ executor,
139
+ application,
140
+ window : & window,
141
+ renderer,
142
+ } )
143
+ . unwrap ( ) ;
130
144
}
0 commit comments