Skip to content

Instantly share code, notes, and snippets.

@thebluefish
Last active November 17, 2023 20:30
Show Gist options
  • Save thebluefish/dd46aa3a0767f53868dae3840311cb39 to your computer and use it in GitHub Desktop.
Save thebluefish/dd46aa3a0767f53868dae3840311cb39 to your computer and use it in GitHub Desktop.
use bevy::prelude::*;
use bevy::reflect::{ReflectFromPtr, ReflectMut};
/// Example demonstrating how to print and mutate the resources of a world using reflection
fn main() {
App::new()
.init_resource::<AppTypeRegistry>()
.register_type::<Foo>()
.register_type::<Bar>()
.insert_resource(Foo::A)
.insert_resource(Bar {
b: 3,
})
.add_systems(Update, (print_resources, update_resources, print_resources).chain())
.run();
}
#[derive(Debug, Clone, Reflect, Resource)]
enum Foo {
A,
B(usize),
C(usize, usize),
}
#[derive(Reflect, Resource)]
pub struct Bar {
b: usize,
}
/// Print all reflectable resources currently in the World
fn print_resources(world: &mut World) {
world.resource_scope(|world: &mut World, type_registry: Mut<AppTypeRegistry>| {
let type_registry = type_registry.read();
for registration in type_registry.iter() {
if let Some(component_id) = world.components().get_resource_id(registration.type_id()) {
let res = world.get_resource_mut_by_id(component_id).unwrap();
let reflect_from_ptr = registration.data::<ReflectFromPtr>().unwrap();
let val: Mut<dyn Reflect> = res.map_unchanged(|ptr| unsafe { reflect_from_ptr.as_reflect_mut(ptr) });
println!("{:?}", val);
}
}
});
}
/// Doubles `Bar`
/// Changes `Foo:A` to `Foo::B`
/// todo: make this DRY
fn update_resources(world: &mut World) {
world.resource_scope(|world: &mut World, type_registry: Mut<AppTypeRegistry>| {
let type_registry = type_registry.read();
for registration in type_registry.iter() {
if let Some(component_id) = world.components().get_resource_id(registration.type_id()) {
let res = world.get_resource_mut_by_id(component_id).unwrap();
let reflect_from_ptr = registration.data::<ReflectFromPtr>().unwrap();
let mut val: Mut<dyn Reflect> = res.map_unchanged(|ptr| unsafe { reflect_from_ptr.as_reflect_mut(ptr) });
match val.reflect_mut() {
ReflectMut::Struct(item) => {
if item.reflect_short_type_path() == "Bar" {
let b = item.field_mut("b").unwrap().downcast_mut::<usize>().unwrap();
*b *= 2;
}
}
ReflectMut::Enum(item) => {
if item.variant_name() == "A" {
item.apply(&Foo::B(0));
}
}
_ => unimplemented!()
}
}
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment