@@ -12,6 +12,7 @@ pub mod tasks;
12
12
pub mod texture_registry;
13
13
pub mod utils;
14
14
15
+ use crate :: builder:: FlutterEngineBuilder ;
15
16
use crate :: channel:: { Channel , ChannelRegistrar } ;
16
17
use crate :: ffi:: {
17
18
FlutterPointerDeviceKind , FlutterPointerMouseButtons , FlutterPointerPhase ,
@@ -21,14 +22,13 @@ use crate::plugins::{Plugin, PluginRegistrar};
21
22
use crate :: tasks:: { TaskRunner , TaskRunnerHandler } ;
22
23
use crate :: texture_registry:: { Texture , TextureRegistry } ;
23
24
use crossbeam_channel:: { unbounded, Receiver , Sender } ;
24
- use flutter_engine_sys:: FlutterTask ;
25
+ use flutter_engine_sys:: { FlutterEngineResult , FlutterTask } ;
25
26
use log:: trace;
26
27
use parking_lot:: RwLock ;
27
28
use std:: ffi:: CString ;
28
29
use std:: future:: Future ;
29
30
use std:: os:: raw:: { c_char, c_void} ;
30
31
use std:: path:: { Path , PathBuf } ;
31
- use std:: sync:: atomic:: { AtomicPtr , Ordering } ;
32
32
use std:: sync:: { Arc , Weak } ;
33
33
use std:: time:: { Instant , SystemTime , UNIX_EPOCH } ;
34
34
use std:: { mem, ptr} ;
@@ -45,7 +45,7 @@ pub(crate) enum MainThreadCallback {
45
45
46
46
struct FlutterEngineInner {
47
47
handler : Weak < dyn FlutterEngineHandler > ,
48
- engine_ptr : AtomicPtr < flutter_engine_sys:: _FlutterEngine > ,
48
+ engine_ptr : flutter_engine_sys:: FlutterEngine ,
49
49
plugins : RwLock < PluginRegistrar > ,
50
50
platform_runner : TaskRunner ,
51
51
_platform_runner_handler : Arc < PlatformRunnerHandler > ,
@@ -142,11 +142,25 @@ impl TaskRunnerHandler for PlatformRunnerHandler {
142
142
}
143
143
144
144
impl FlutterEngine {
145
- pub ( crate ) fn new (
146
- handler : Weak < dyn FlutterEngineHandler > ,
147
- assets : PathBuf ,
148
- arguments : Vec < String > ,
149
- ) ->Self {
145
+ pub ( crate ) fn new ( builder : FlutterEngineBuilder ) ->Result < Self , CreateError > {
146
+ // Convert arguments into flutter compatible
147
+ let mut args =Vec :: with_capacity ( builder. args . len ( ) +2 ) ;
148
+ args. push ( CString :: new ( "flutter-rs" ) . unwrap ( ) . into_raw ( ) ) ;
149
+ args. push (
150
+ CString :: new ( "--icu-symbol-prefix=gIcudtl" )
151
+ . unwrap ( )
152
+ . into_raw ( ) ,
153
+ ) ;
154
+ for argin builder. args . iter ( ) {
155
+ args. push ( CString :: new ( arg. as_str ( ) ) . unwrap ( ) . into_raw ( ) ) ;
156
+ }
157
+
158
+ // Extract handler
159
+ let handler = builder. handler . expect ( "No handler set" ) ;
160
+ if !handler. upgrade ( ) . is_some ( ) {
161
+ return Err ( CreateError :: NoHandler ) ;
162
+ }
163
+
150
164
let platform_handler =Arc :: new ( PlatformRunnerHandler {
151
165
handler : handler. clone ( ) ,
152
166
} ) ;
@@ -156,7 +170,7 @@ impl FlutterEngine {
156
170
let engine =Self {
157
171
inner : Arc :: new ( FlutterEngineInner {
158
172
handler,
159
- engine_ptr : AtomicPtr :: new ( ptr:: null_mut ( ) ) ,
173
+ engine_ptr : ptr:: null_mut ( ) ,
160
174
plugins : RwLock :: new ( PluginRegistrar :: new ( ) ) ,
161
175
platform_runner : TaskRunner :: new (
162
176
Arc :: downgrade ( & platform_handler) as Weak < dyn TaskRunnerHandler >
@@ -165,107 +179,16 @@ impl FlutterEngine {
165
179
platform_receiver : main_rx,
166
180
platform_sender : main_tx,
167
181
texture_registry : TextureRegistry :: new ( ) ,
168
- assets,
169
- arguments,
182
+ assets : builder . assets ,
183
+ arguments : builder . args ,
170
184
} ) ,
171
185
} ;
172
186
173
187
let inner =& engine. inner ;
174
188
inner. plugins . write ( ) . init ( engine. downgrade ( ) ) ;
175
189
inner. platform_runner . init ( engine. downgrade ( ) ) ;
176
190
177
- engine
178
- }
179
-
180
- #[ inline]
181
- pub fn engine_ptr ( & self ) -> flutter_engine_sys:: FlutterEngine {
182
- self . inner . engine_ptr . load ( Ordering :: Relaxed )
183
- }
184
-
185
- pub fn add_plugin < P > ( & self , plugin : P ) ->& Self
186
- where
187
- P : Plugin +' static ,
188
- {
189
- self . inner . plugins . write ( ) . add_plugin ( plugin) ;
190
- self
191
- }
192
-
193
- pub fn with_plugin < F , P > ( & self , f : F )
194
- where
195
- F : FnOnce ( & P ) ,
196
- P : Plugin +' static ,
197
- {
198
- self . inner . plugins . read ( ) . with_plugin ( f)
199
- }
200
-
201
- pub fn with_plugin_mut < F , P > ( & self , f : F )
202
- where
203
- F : FnOnce ( & mut P ) ,
204
- P : Plugin +' static ,
205
- {
206
- self . inner . plugins . write ( ) . with_plugin_mut ( f)
207
- }
208
-
209
- pub fn remove_channel ( & self , channel_name : & str ) ->Option < Arc < dyn Channel > > {
210
- self . inner
211
- . plugins
212
- . write ( )
213
- . channel_registry
214
- . remove_channel ( channel_name)
215
- }
216
-
217
- pub fn with_channel < F > ( & self , channel_name : & str , f : F )
218
- where
219
- F : FnOnce ( & dyn Channel ) ,
220
- {
221
- self . inner
222
- . plugins
223
- . read ( )
224
- . channel_registry
225
- . with_channel ( channel_name, f)
226
- }
227
-
228
- pub fn with_channel_registrar < F > ( & self , plugin_name : & ' static str , f : F )
229
- where
230
- F : FnOnce ( & mut ChannelRegistrar ) ,
231
- {
232
- self . inner
233
- . plugins
234
- . write ( )
235
- . channel_registry
236
- . with_channel_registrar ( plugin_name, f)
237
- }
238
-
239
- pub fn downgrade ( & self ) ->FlutterEngineWeakRef {
240
- FlutterEngineWeakRef {
241
- inner : Arc :: downgrade ( & self . inner ) ,
242
- }
243
- }
244
-
245
- pub fn assets ( & self ) ->& Path {
246
- & self . inner . assets
247
- }
248
-
249
- pub fn arguments ( & self ) ->& Vec < String > {
250
- & self . inner . arguments
251
- }
252
-
253
- pub fn run ( & self ) ->Result < ( ) , RunError > {
254
- if !self . is_platform_thread ( ) {
255
- return Err ( RunError :: NotPlatformThread ) ;
256
- }
257
-
258
- let mut args =Vec :: with_capacity ( self . inner . arguments . len ( ) +2 ) ;
259
- args. push ( CString :: new ( "flutter-rs" ) . unwrap ( ) . into_raw ( ) ) ;
260
- args. push (
261
- CString :: new ( "--icu-symbol-prefix=gIcudtl" )
262
- . unwrap ( )
263
- . into_raw ( ) ,
264
- ) ;
265
- for argin self . inner . arguments . iter ( ) {
266
- args. push ( CString :: new ( arg. as_str ( ) ) . unwrap ( ) . into_raw ( ) ) ;
267
- }
268
-
191
+ // Configure renderer
269
192
let renderer_config = flutter_engine_sys:: FlutterRendererConfig {
270
193
type_ : flutter_engine_sys:: FlutterRendererType :: kOpenGL,
271
194
__bindgen_anon_1 : flutter_engine_sys:: FlutterRendererConfig__bindgen_ty_1 {
@@ -287,9 +210,10 @@ impl FlutterEngine {
287
210
} ,
288
211
} ;
289
212
213
+ // Configure engine threads
290
214
// TODO: Should be downgraded to a weak once weak::into_raw lands in stable
291
215
let runner_ptr ={
292
- let arc =self . inner . platform_runner . clone ( ) . inner ;
216
+ let arc = inner. platform_runner . clone ( ) . inner ;
293
217
Arc :: into_raw ( arc) as * mut std:: ffi:: c_void
294
218
} ;
295
219
@@ -310,9 +234,10 @@ impl FlutterEngine {
310
234
as * const flutter_engine_sys:: FlutterTaskRunnerDescription ,
311
235
} ;
312
236
237
+ // Configure engine
313
238
let project_args = flutter_engine_sys:: FlutterProjectArgs {
314
239
struct_size : std:: mem:: size_of :: < flutter_engine_sys:: FlutterProjectArgs > ( ) ,
315
- assets_path : path_to_cstring ( self . assets ( ) ) . into_raw ( ) ,
240
+ assets_path : path_to_cstring ( & inner . assets ) . into_raw ( ) ,
316
241
main_path__unused__ : std:: ptr:: null ( ) ,
317
242
packages_path__unused__ : std:: ptr:: null ( ) ,
318
243
icu_data_path : std:: ptr:: null ( ) ,
@@ -340,25 +265,111 @@ impl FlutterEngine {
340
265
compositor : std:: ptr:: null ( ) ,
341
266
} ;
342
267
268
+ // Initialise engine
343
269
unsafe {
344
270
// TODO: Should be downgraded to a weak once weak::into_raw lands in stable
345
- let inner_ptr =Arc :: into_raw ( self . inner . clone ( ) ) as * mut std:: ffi:: c_void ;
271
+ let inner_ptr =Arc :: into_raw ( inner. clone ( ) ) as * mut std:: ffi:: c_void ;
346
272
347
- let engine_ptr: flutter_engine_sys:: FlutterEngine = std:: ptr:: null_mut ( ) ;
348
- if flutter_engine_sys:: FlutterEngineRun (
273
+ if flutter_engine_sys:: FlutterEngineInitialize (
349
274
1 ,
350
275
& renderer_config,
351
276
& project_args,
352
277
inner_ptr,
353
- & engine_ptras * const flutter_engine_sys:: FlutterEngine
278
+ & inner . engine_ptr as * const flutter_engine_sys:: FlutterEngine
354
279
as * mut flutter_engine_sys:: FlutterEngine ,
355
280
) != flutter_engine_sys:: FlutterEngineResult :: kSuccess
356
- || engine_ptr. is_null ( )
281
+ ||inner . engine_ptr . is_null ( )
357
282
{
358
- Err ( RunError :: EnginePtrNull )
283
+ Err ( CreateError :: EnginePtrNull )
359
284
} else {
360
- self . inner . engine_ptr . store ( engine_ptr, Ordering :: Relaxed ) ;
361
- Ok ( ( ) )
285
+ Ok ( engine)
286
+ }
287
+ }
288
+ }
289
+
290
+ #[ inline]
291
+ pub fn engine_ptr ( & self ) -> flutter_engine_sys:: FlutterEngine {
292
+ self . inner . engine_ptr
293
+ }
294
+
295
+ pub fn add_plugin < P > ( & self , plugin : P ) ->& Self
296
+ where
297
+ P : Plugin +' static ,
298
+ {
299
+ self . inner . plugins . write ( ) . add_plugin ( plugin) ;
300
+ self
301
+ }
302
+
303
+ pub fn with_plugin < F , P > ( & self , f : F )
304
+ where
305
+ F : FnOnce ( & P ) ,
306
+ P : Plugin +' static ,
307
+ {
308
+ self . inner . plugins . read ( ) . with_plugin ( f)
309
+ }
310
+
311
+ pub fn with_plugin_mut < F , P > ( & self , f : F )
312
+ where
313
+ F : FnOnce ( & mut P ) ,
314
+ P : Plugin +' static ,
315
+ {
316
+ self . inner . plugins . write ( ) . with_plugin_mut ( f)
317
+ }
318
+
319
+ pub fn remove_channel ( & self , channel_name : & str ) ->Option < Arc < dyn Channel > > {
320
+ self . inner
321
+ . plugins
322
+ . write ( )
323
+ . channel_registry
324
+ . remove_channel ( channel_name)
325
+ }
326
+
327
+ pub fn with_channel < F > ( & self , channel_name : & str , f : F )
328
+ where
329
+ F : FnOnce ( & dyn Channel ) ,
330
+ {
331
+ self . inner
332
+ . plugins
333
+ . read ( )
334
+ . channel_registry
335
+ . with_channel ( channel_name, f)
336
+ }
337
+
338
+ pub fn with_channel_registrar < F > ( & self , plugin_name : & ' static str , f : F )
339
+ where
340
+ F : FnOnce ( & mut ChannelRegistrar ) ,
341
+ {
342
+ self . inner
343
+ . plugins
344
+ . write ( )
345
+ . channel_registry
346
+ . with_channel_registrar ( plugin_name, f)
347
+ }
348
+
349
+ pub fn downgrade ( & self ) ->FlutterEngineWeakRef {
350
+ FlutterEngineWeakRef {
351
+ inner : Arc :: downgrade ( & self . inner ) ,
352
+ }
353
+ }
354
+
355
+ pub fn assets ( & self ) ->& Path {
356
+ & self . inner . assets
357
+ }
358
+
359
+ pub fn arguments ( & self ) ->& Vec < String > {
360
+ & self . inner . arguments
361
+ }
362
+
363
+ pub fn run ( & self ) ->Result < ( ) , ( ) > {
364
+ if !self . is_platform_thread ( ) {
365
+ panic ! ( "Not on platform thread" ) ;
366
+ }
367
+
368
+ // TODO: Safeguard, process results
369
+ unsafe {
370
+ match flutter_engine_sys:: FlutterEngineRunInitialized ( self . engine_ptr ( ) ) {
371
+ FlutterEngineResult :: kSuccess =>Ok ( ( ) ) ,
372
+ _ =>Err ( ( ) ) ,
362
373
}
363
374
}
364
375
}
@@ -587,19 +598,19 @@ fn path_to_cstring(path: &Path) -> CString {
587
598
}
588
599
589
600
#[ derive( Debug , Eq , PartialEq ) ]
590
- pub enum RunError {
591
- NotPlatformThread ,
601
+ pub enum CreateError {
602
+ NoHandler ,
592
603
EnginePtrNull ,
593
604
}
594
605
595
- impl core:: fmt:: Display for RunError {
606
+ impl core:: fmt:: Display for CreateError {
596
607
fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> core:: fmt:: Result {
597
608
let msg =match self {
598
- RunError :: NotPlatformThread =>"Not on platform thread ." ,
599
- RunError :: EnginePtrNull =>"Engine ptr is null." ,
609
+ CreateError :: NoHandler =>"No handler set ." ,
610
+ CreateError :: EnginePtrNull =>"Engine ptr is null." ,
600
611
} ;
601
612
writeln ! ( f, "{}" , msg)
602
613
}
603
614
}
604
615
605
- impl std:: error:: Error for RunError { }
616
+ impl std:: error:: Error for CreateError { }