@@ -493,6 +493,102 @@ impl<'w, 's> Commands<'w, 's> {
493
493
self . queue . push ( remove_resource :: < R > ) ;
494
494
}
495
495
496
+ /// Pushes a [`Command`] to the queue for inserting a non-[`Send`] resource in the [`World`] with an inferred value.
497
+ ///
498
+ /// See [`World::init_non_send_resource`] for more details.
499
+ ///
500
+ /// # Example
501
+ ///
502
+ /// ```
503
+ /// # use bevy::prelude::*;
504
+ /// #
505
+ /// struct MyNonSend(*const u8);
506
+ ///
507
+ /// impl Default for MyNonSend {
508
+ /// fn default() -> Self {
509
+ /// MyNonSend(std::ptr::null())
510
+ /// }
511
+ /// }
512
+ ///
513
+ /// fn create_my_non_send(mut commands: Commands) {
514
+ /// commands.init_non_send_resource::<MyNonSend>();
515
+ /// }
516
+ /// #
517
+ /// # App::new()
518
+ /// # .add_systems(Startup, (create_my_non_send, check).chain())
519
+ /// # .run();
520
+ /// #
521
+ /// # fn check(my_non_send: NonSend<MyNonSend>) {
522
+ /// # assert!(my_non_send.0.is_null());
523
+ /// # }
524
+ /// ```
525
+ pub fn init_non_send_resource < R : FromWorld + ' static > ( & mut self ) {
526
+ self . queue . push ( init_non_send_resource :: < R > ) ;
527
+ }
528
+
529
+ /// Pushes a [`Command`] to the queue for inserting a non-[`Send`] resource in the [`World`] with an specific value.
530
+ ///
531
+ /// Note that this command takes a closure, not a value. This closure is executed on the main thread and should return
532
+ /// the value of the non-[`Send`] resource. The closure itself must be [`Send`], but its returned value does not need to be.
533
+ ///
534
+ /// See [`World::insert_non_send_resource`] for more details.
535
+ ///
536
+ /// # Example
537
+ ///
538
+ /// ```
539
+ /// # use bevy::prelude::*;
540
+ /// #
541
+ /// struct MyNonSend(*const u8);
542
+ ///
543
+ /// fn create_my_non_send(mut commands: Commands) {
544
+ /// // Note that this is a closure:
545
+ /// commands.insert_non_send_resource(|| {
546
+ /// MyNonSend(std::ptr::null())
547
+ /// });
548
+ /// }
549
+ /// #
550
+ /// # App::new()
551
+ /// # .add_systems(Startup, (create_my_non_send, check).chain())
552
+ /// # .run();
553
+ /// #
554
+ /// # fn check(my_non_send: NonSend<MyNonSend>) {
555
+ /// # assert!(my_non_send.0.is_null());
556
+ /// # }
557
+ /// ```
558
+ pub fn insert_non_send_resource < F , R > ( & mut self , func : F )
559
+ where
560
+ F : FnOnce ( ) -> R + Send + ' static ,
561
+ R : ' static ,
562
+ {
563
+ self . queue . push ( insert_non_send_resource ( func) ) ;
564
+ }
565
+
566
+ /// Pushes a [`Command`] to the queue for removing a non-[`Send`] resource from the [`World`].
567
+ ///
568
+ /// See [`World::remove_non_send_resource`] for more details.
569
+ ///
570
+ /// ```
571
+ /// # use bevy::prelude::*;
572
+ /// #
573
+ /// struct MyNonSend(*const u8);
574
+ ///
575
+ /// fn remove_my_non_send(mut commands: Commands) {
576
+ /// commands.remove_non_send_resource::<MyNonSend>();
577
+ /// }
578
+ /// #
579
+ /// # App::new()
580
+ /// # .insert_non_send_resource(MyNonSend(std::ptr::null()))
581
+ /// # .add_systems(Startup, (remove_my_non_send, check).chain())
582
+ /// # .run();
583
+ /// #
584
+ /// # fn check(my_non_send: Option<NonSend<MyNonSend>>) {
585
+ /// # assert!(my_non_send.is_none());
586
+ /// # }
587
+ /// ```
588
+ pub fn remove_non_send_resource < R : ' static > ( & mut self ) {
589
+ self . queue . push ( remove_non_send_resource :: < R > ) ;
590
+ }
591
+
496
592
/// Runs the system corresponding to the given [`SystemId`].
497
593
/// Systems are ran in an exclusive and single threaded way.
498
594
/// Running slow systems can become a bottleneck.
@@ -1134,6 +1230,30 @@ fn remove_resource<R: Resource>(world: &mut World) {
1134
1230
world. remove_resource :: < R > ( ) ;
1135
1231
}
1136
1232
1233
+ /// A [`Command`] that inserts a non-[`Send`] resource `R` into the world using
1234
+ /// a value created with the [`FromWorld`] trait.
1235
+ fn init_non_send_resource < R : FromWorld + ' static > ( world : & mut World ) {
1236
+ world. init_non_send_resource :: < R > ( ) ;
1237
+ }
1238
+
1239
+ /// A [`Command`] that removes a non-[`Send`] resource `R` from the world.
1240
+ fn remove_non_send_resource < R : ' static > ( world : & mut World ) {
1241
+ world. remove_non_send_resource :: < R > ( ) ;
1242
+ }
1243
+
1244
+ /// A [`Command`] that inserts a non-[`Send`] resource into the world by calling
1245
+ /// `func` on the main thread and inserting its returned value.
1246
+ fn insert_non_send_resource < F , R > ( func : F ) -> impl Command
1247
+ where
1248
+ // `R` is not `Send`, but the function is!
1249
+ F : FnOnce ( ) -> R + Send + ' static ,
1250
+ R : ' static ,
1251
+ {
1252
+ move |world : & mut World | {
1253
+ world. insert_non_send_resource ( ( func) ( ) ) ;
1254
+ }
1255
+ }
1256
+
1137
1257
/// [`EntityCommand`] to log the components of a given entity. See [`EntityCommands::log_components`].
1138
1258
fn log_components ( entity : Entity , world : & mut World ) {
1139
1259
let debug_infos: Vec < _ > = world
0 commit comments