Allow SceneMapSerializer to accept Box<dyn Reflect>s as well
#17622
+41
−6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
NOTE: This is NOT a working PR! See below.
Currently,
SceneMapSerializerlooks like this:Which works fine for the use-case of
SceneSerializerandEntitySerializer, since components there arePartialReflects. However, I want to serialize aVec<Box<dyn Reflect>>using this serializer, which is currently impossible without cloning theBox<dyn Reflect>s first.Solution
This PR attempts to solve this issue by changing the signature to:
Since the serializer logic doesn't actually need a
Box<dyn PartialReflect>, it just needs some way to get a&dyn PartialReflectfrom the entry. This means thatVec<Box<dyn PartialReflect>>,Vec<&dyn PartialReflect>, andVec<Arc<dyn PartialReflect>>can all be serialized now.However, this doesn't solve the original issue of serializing
Box<dyn Reflect>s since that doesn'timpl AsRef<dyn PartialReflect>. I'm not sure how to solve this, so I'd like to open this PR and see if anyone else has a good idea on how to achieve this.Current ideas:
CastPartialReflectfrom bevy_reflect: Add casting traits to supportBoxand other wrapper types #15532Vec<&dyn PartialReflect>andVec<&dyn Reflect>could be accepted into the same interfaceentriesaimpl Iterator<Item = impl AsRef<dyn PartialReflect>>, and manuallyentries.iter().map(Reflect::as_partial_reflect)when constructing theSceneMapSerializerserde::Serializesincefn serialize(&self)takes a shared ref toself, but we would need to mutate the iterator to use it (unless we mutex, but like, really?)serde::Serializewe can use?Vec<&dyn Reflect>but you need to do that iterator mapping trick, so it's not quite as clean as the first solutionimpl Iterator<Item = impl CastPartialReflect>?SceneMapSerializer?Testing
Added a unit test to
serde.rswhich should be used to validate the outcome of this PR. It checks that passing in different combinations ofBox<..>,Arc<..>,PartialReflectandReflectall compile.Migration Guide