Skip to content

Commit 1813cda

Browse files
committed
make display without world more sensible
1 parent 5ba4cb4 commit 1813cda

File tree

3 files changed

+298
-112
lines changed

3 files changed

+298
-112
lines changed

crates/bevy_mod_scripting_core/src/bindings/pretty_print.rs

Lines changed: 109 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -66,49 +66,76 @@ impl ReflectReferencePrinter {
6666
Self { reference }
6767
}
6868

69-
fn pretty_print_base(base: &ReflectBaseType, world: WorldGuard, out: &mut String) {
70-
let type_id = base.type_id;
71-
let type_path = type_id.display_with_world(world.clone());
72-
73-
let base_kind = match base.base_id {
74-
ReflectBase::Component(e, _) => format!("Component on entity {}", e),
75-
ReflectBase::Resource(_) => "Resource".to_owned(),
76-
ReflectBase::Owned(ref id) => format!("Allocation({})", id),
77-
};
78-
79-
out.push_str(&format!("{}({})", base_kind, type_path));
80-
}
81-
8269
/// Given a reflect reference, prints the type path of the reference resolving the type names with short names.
8370
/// I.e. `MyType(Component).field_name[0].field_name[1] -> FieldType::Name`
84-
pub fn pretty_print(&self, world: WorldGuard) -> String {
71+
pub fn pretty_print(&self, world: Option<WorldGuard>) -> String {
8572
let mut pretty_path = String::new();
8673

8774
pretty_path.push_str("<Reference to ");
75+
if let Some(world) = world {
76+
let tail_type_id = self.reference.tail_type_id(world.clone()).ok().flatten();
77+
let type_registry = world.type_registry();
8878

89-
let tail_type_id = self.reference.tail_type_id(world.clone()).ok().flatten();
90-
let type_registry = world.type_registry();
91-
92-
Self::pretty_print_base(&self.reference.base, world.clone(), &mut pretty_path);
79+
Self::pretty_print_base(&self.reference.base, Some(world), &mut pretty_path);
9380

94-
pretty_path.push_str(&self.reference.reflect_path.to_string());
81+
pretty_path.push_str(&self.reference.reflect_path.to_string());
9582

96-
if let Some(tail_type_id) = tail_type_id {
97-
let type_path = {
98-
let type_registry = type_registry.read();
99-
type_registry
100-
.get_type_info(tail_type_id)
101-
.map(|t| t.type_path_table().short_path())
102-
.unwrap_or(Self::UNREGISTERED_TYPE)
103-
};
104-
pretty_path.push_str(&format!(" -> {}", type_path));
83+
if let Some(tail_type_id) = tail_type_id {
84+
let type_path = {
85+
let type_registry = type_registry.read();
86+
type_registry
87+
.get_type_info(tail_type_id)
88+
.map(|t| t.type_path_table().short_path())
89+
.unwrap_or(Self::UNREGISTERED_TYPE)
90+
};
91+
pretty_path.push_str(&format!(" -> {}", type_path));
92+
}
93+
} else {
94+
Self::pretty_print_base(&self.reference.base, None, &mut pretty_path);
10595
}
106-
10796
pretty_path.push('>');
108-
10997
pretty_path
11098
}
11199

100+
/// Prints the actual value of the reference. Tries to use best available method to print the value.
101+
pub fn pretty_print_value(&self, world: Option<WorldGuard>) -> String {
102+
let mut output = String::new();
103+
104+
match world {
105+
Some(world) => {
106+
// instead of relying on type registrations, simply traverse the reflection tree and print sensible values
107+
self.reference
108+
.with_reflect(world, |r| {
109+
self.pretty_print_value_inner(r, &mut output);
110+
})
111+
.unwrap_or_else(|e| {
112+
output.push_str(&format!("<Error in printing: {}>", e));
113+
});
114+
}
115+
None => {
116+
output.push_str("<Referenced Value>");
117+
}
118+
}
119+
120+
output
121+
}
122+
123+
fn pretty_print_base(base: &ReflectBaseType, world: Option<WorldGuard>, out: &mut String) {
124+
let type_id = base.type_id;
125+
let type_path = if let Some(world) = world {
126+
type_id.display_with_world(world.clone())
127+
} else {
128+
format!("{:?}", type_id)
129+
};
130+
131+
let base_kind = match base.base_id {
132+
ReflectBase::Component(e, _) => format!("Component on entity {}", e),
133+
ReflectBase::Resource(_) => "Resource".to_owned(),
134+
ReflectBase::Owned(ref id) => format!("Allocation({})", id),
135+
};
136+
137+
out.push_str(&format!("{}({})", base_kind, type_path));
138+
}
112139
pub fn pretty_print_value_opaque(&self, v: &dyn PartialReflect, output: &mut String) {
113140
let type_id = v
114141
.get_represented_type_info()
@@ -144,22 +171,6 @@ impl ReflectReferencePrinter {
144171
output.push(')');
145172
}
146173

147-
/// Prints the actual value of the reference. Tries to use best available method to print the value.
148-
pub fn pretty_print_value(&self, world: WorldGuard) -> String {
149-
let mut output = String::new();
150-
151-
// instead of relying on type registrations, simply traverse the reflection tree and print sensible values
152-
self.reference
153-
.with_reflect(world, |r| {
154-
self.pretty_print_value_inner(r, &mut output);
155-
})
156-
.unwrap_or_else(|e| {
157-
output.push_str(&format!("<Error in printing: {}>", e));
158-
});
159-
160-
output
161-
}
162-
163174
fn pretty_print_key_values<
164175
K: AsRef<str>,
165176
V: AsRef<str>,
@@ -302,13 +313,15 @@ impl ReflectReferencePrinter {
302313
}
303314
}
304315

305-
/// Alais for [`DisplayWithWorldAndDummy`] + [`std::fmt::Display`], ideally display should warn that it's not the full representation.
306-
pub trait DisplayWithWorldAndDummy: DisplayWithWorld + std::fmt::Display {}
307-
impl<T: DisplayWithWorld + std::fmt::Display> DisplayWithWorldAndDummy for T {}
316+
// /// Alais for [`DisplayWithWorldAndDummy`] + [`std::fmt::Display`], ideally display should warn that it's not the full representation.
317+
// pub trait DisplayWithWorldAndDummy: DisplayWithWorld + std::fmt::Display {}
318+
// impl<T: DisplayWithWorld + std::fmt::Display> DisplayWithWorldAndDummy for T {}
308319

309320
/// For types which can't be pretty printed without world access.
310321
/// Implementors should try to print the best value they can, and never panick.
311322
pub trait DisplayWithWorld: std::fmt::Debug {
323+
fn display_without_world(&self) -> String;
324+
312325
/// Display the `shallowest` representation of the type using world access.
313326
/// For references this is the type path and the type of the value they are pointing to.
314327
fn display_with_world(&self, world: WorldGuard) -> String;
@@ -320,42 +333,36 @@ pub trait DisplayWithWorld: std::fmt::Debug {
320333
}
321334
}
322335

323-
#[macro_export]
324-
macro_rules! impl_dummy_display (
325-
($t:ty) => {
326-
impl std::fmt::Display for $t {
327-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
328-
write!(f, "<use display_with_world instead: {:#?}>", stringify!($t))?;
329-
Ok(())
330-
}
331-
}
332-
};
333-
);
334-
335-
impl_dummy_display!(ReflectReference);
336-
337336
impl DisplayWithWorld for ReflectReference {
338337
fn display_with_world(&self, world: WorldGuard) -> String {
339-
ReflectReferencePrinter::new(self.clone()).pretty_print(world)
338+
ReflectReferencePrinter::new(self.clone()).pretty_print(Some(world))
340339
}
341340

342341
fn display_value_with_world(&self, world: WorldGuard) -> String {
343-
ReflectReferencePrinter::new(self.clone()).pretty_print_value(world)
342+
ReflectReferencePrinter::new(self.clone()).pretty_print_value(Some(world))
344343
}
345-
}
346344

347-
impl_dummy_display!(ReflectBaseType);
345+
fn display_without_world(&self) -> String {
346+
ReflectReferencePrinter::new(self.clone()).pretty_print(None)
347+
}
348+
}
348349

349350
impl DisplayWithWorld for ReflectBaseType {
350351
fn display_with_world(&self, world: WorldGuard) -> String {
351352
let mut string = String::new();
352-
ReflectReferencePrinter::pretty_print_base(self, world, &mut string);
353+
ReflectReferencePrinter::pretty_print_base(self, Some(world), &mut string);
353354
string
354355
}
355356

356357
fn display_value_with_world(&self, world: WorldGuard) -> String {
357358
self.display_with_world(world)
358359
}
360+
361+
fn display_without_world(&self) -> String {
362+
let mut string = String::new();
363+
ReflectReferencePrinter::pretty_print_base(self, None, &mut string);
364+
string
365+
}
359366
}
360367

361368
impl DisplayWithWorld for TypeId {
@@ -382,9 +389,11 @@ impl DisplayWithWorld for TypeId {
382389
fn display_value_with_world(&self, world: WorldGuard) -> String {
383390
self.display_with_world(world)
384391
}
385-
}
386392

387-
impl_dummy_display!(ScriptValue);
393+
fn display_without_world(&self) -> String {
394+
format!("{:?}", self)
395+
}
396+
}
388397

389398
impl DisplayWithWorld for ScriptValue {
390399
fn display_with_world(&self, world: WorldGuard) -> String {
@@ -404,16 +413,32 @@ impl DisplayWithWorld for ScriptValue {
404413
ScriptValue::Float(f) => f.to_string(),
405414
ScriptValue::String(cow) => cow.to_string(),
406415
ScriptValue::Error(script_error) => script_error.display_with_world(world),
416+
ScriptValue::List(vec) => vec.display_without_world(),
417+
}
418+
}
419+
420+
fn display_without_world(&self) -> String {
421+
match self {
422+
ScriptValue::Unit => "()".to_owned(),
423+
ScriptValue::Bool(b) => b.to_string(),
424+
ScriptValue::Integer(i) => i.to_string(),
425+
ScriptValue::Float(f) => f.to_string(),
426+
ScriptValue::String(cow) => cow.to_string(),
407427
ScriptValue::List(vec) => {
408428
let mut string = String::new();
409429
ReflectReferencePrinter::pretty_print_key_values(
410430
BracketType::Square,
411431
vec.iter()
412-
.map(|v| (None::<String>, v.display_value_with_world(world.clone()))),
432+
.map(|v| (None::<String>, v.display_without_world())),
413433
&mut string,
414434
);
415435
string
416436
}
437+
ScriptValue::Reference(reflect_reference) => reflect_reference.display_without_world(),
438+
ScriptValue::Function(dynamic_script_function_mut) => {
439+
format!("Function({})", dynamic_script_function_mut.name())
440+
}
441+
ScriptValue::Error(interop_error) => interop_error.display_without_world(),
417442
}
418443
}
419444
}
@@ -444,4 +469,17 @@ impl<T: DisplayWithWorld> DisplayWithWorld for Vec<T> {
444469
});
445470
string
446471
}
472+
473+
fn display_without_world(&self) -> String {
474+
let mut string = String::new();
475+
BracketType::Square.surrounded(&mut string, |string| {
476+
for (i, v) in self.iter().enumerate() {
477+
string.push_str(&v.display_without_world());
478+
if i != self.len() - 1 {
479+
string.push_str(", ");
480+
}
481+
}
482+
});
483+
string
484+
}
447485
}

0 commit comments

Comments
 (0)