Skip to content

Commit 43c9c2f

Browse files
committed
feat: refactor handler context into system param
1 parent 8be2090 commit 43c9c2f

File tree

11 files changed

+491
-298
lines changed

11 files changed

+491
-298
lines changed

crates/bevy_mod_scripting_core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ itertools = "0.13"
4040
derivative = "2.2"
4141
profiling = { workspace = true }
4242
bevy_mod_scripting_derive = { workspace = true }
43+
fixedbitset = "0.5"
4344

4445
[dev-dependencies]
4546
test_utils = { workspace = true }

crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use bevy::{
1212
reflect::{PartialReflect, ReflectRef},
1313
};
1414
use itertools::Itertools;
15-
use std::{any::TypeId, borrow::Cow};
15+
use std::{
16+
any::{Any, TypeId},
17+
borrow::Cow,
18+
};
1619

1720
/// A utility for printing reflect references in a human readable format.
1821
pub struct ReflectReferencePrinter {
@@ -325,7 +328,7 @@ impl ReflectReferencePrinter {
325328

326329
/// For types which can't be pretty printed without world access.
327330
/// Implementors should try to print the best value they can, and never panick.
328-
pub trait DisplayWithWorld: std::fmt::Debug {
331+
pub trait DisplayWithWorld: std::fmt::Debug + AsAny {
329332
/// # Warning
330333
/// Display this type without world access. It is not recommended to use this method for anything other than debugging or necessary trait impl corners.
331334
/// For many types this will just print type id's with no further information.
@@ -343,6 +346,27 @@ pub trait DisplayWithWorld: std::fmt::Debug {
343346
self.display_with_world(world)
344347
}
345348
}
349+
350+
#[doc(hidden)]
351+
pub trait AsAny: 'static {
352+
fn as_any(&self) -> &dyn Any;
353+
}
354+
355+
#[doc(hidden)]
356+
impl<T: DisplayWithWorld + 'static> AsAny for T {
357+
fn as_any(&self) -> &dyn Any {
358+
self
359+
}
360+
}
361+
362+
impl dyn DisplayWithWorld {
363+
/// Downcasts the `DisplayWithWorld` trait object to a concrete type.
364+
/// Trampoline function to allow downcasting of errors.
365+
pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
366+
self.as_any().downcast_ref::<T>()
367+
}
368+
}
369+
346370
#[profiling::all_functions]
347371
impl DisplayWithWorld for ReflectReference {
348372
fn display_with_world(&self, world: WorldGuard) -> String {
@@ -524,7 +548,7 @@ impl DisplayWithWorld for ScriptValue {
524548
}
525549
}
526550
#[profiling::all_functions]
527-
impl<T: DisplayWithWorld> DisplayWithWorld for Vec<T> {
551+
impl<T: DisplayWithWorld + 'static> DisplayWithWorld for Vec<T> {
528552
fn display_with_world(&self, world: WorldGuard) -> String {
529553
let mut string = String::new();
530554
BracketType::Square.surrounded(&mut string, |string| {
@@ -579,7 +603,7 @@ impl DisplayWithWorld for String {
579603
}
580604
}
581605
#[profiling::all_functions]
582-
impl<K: DisplayWithWorld, V: DisplayWithWorld> DisplayWithWorld
606+
impl<K: DisplayWithWorld + 'static, V: DisplayWithWorld + 'static> DisplayWithWorld
583607
for std::collections::HashMap<K, V>
584608
{
585609
fn display_with_world(&self, world: WorldGuard) -> String {

crates/bevy_mod_scripting_core/src/bindings/world.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ impl<'w> WorldAccessGuard<'w> {
9292
o
9393
}
9494

95+
/// Safely allows access to the world for the duration of the closure via a static [`WorldAccessGuard`] using a previously lifetimed world guard.
96+
pub fn with_existing_static_guard<O>(
97+
guard: WorldAccessGuard<'w>,
98+
f: impl FnOnce(WorldGuard<'static>) -> O,
99+
) -> O {
100+
// safety: we invalidate the guard after the closure is called, meaning the world cannot be accessed at all after the 'w lifetime ends
101+
let static_guard: WorldAccessGuard<'static> = unsafe { std::mem::transmute(guard) };
102+
let o = f(static_guard.clone());
103+
104+
static_guard.invalidate();
105+
o
106+
}
107+
95108
/// Creates a new [`WorldAccessGuard`] for the given mutable borrow of the world.
96109
///
97110
/// Creating a guard requires that some resources exist in the world, namely:

0 commit comments

Comments
 (0)