Encapsulate cfg(feature = "track_location")
in a type.
#17602
+763
−1,205
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
Eliminate the need to write
cfg(feature = "track_location")
every time one uses an API that may use location tracking. It's verbose, and a little intimidating. And it requires code outside ofbevy_ecs
that wants to use location tracking needs to either unconditionally enable the feature, or include conditional compilation of its own. It would be good for users to be able to log locations when they are available without needing to add feature flags to their own crates.Reduce the number of cases where code compiles with the
track_location
feature enabled, but not with it disabled, or vice versa. It can be hard to remember to test it both ways!Remove the need to store a
None
inHookContext
when thetrack_location
feature is disabled.Solution
Create an
TrackLocationOption<T>
type that contains aT
if thetrack_location
feature is enabled, and is a ZST if it is not. The overall API is similar toOption
, but whether the value isSome
orNone
is set at compile time and is the same for all values.Create a
MaybeLocation
alias for the common case of&'static Location<'static>
.Remove all
cfg(feature = "track_location")
blocks outside of the implementation of that type, and instead call methods on it.When
track_location
is disabled,TrackLocationOption
is a ZST and all methods are#[inline]
and empty, so they should be entirely removed by the compiler. But the code will still be visible to the compiler and checked, so if it compiles with the feature disabled then it should also compile with it enabled, and vice versa.Open Questions
The names
TrackLocationOption<T>
andMaybeLocation
aren't great. Suggestions for better names are welcome!Where should these types live? I put them in
change_detection
because that's where the existingMaybeLocation
types were, but we now use these outside of change detection.While I believe that the compiler should be able to remove all of these calls, I have not actually tested anything. If we want to take this approach, what testing is required to ensure it doesn't impact performance?
Migration Guide
Methods like
Ref::changed_by()
that return a&'static Location<'static>
will now be available even when thetrack_location
feature is disabled, but they will return a newMaybeLocation
type.MaybeLocation
wraps a&'static Location<'static>
when the feature is enabled, and is a ZST when the feature is disabled.Existing code that needs a
&Location
can callinto_inner()
to recover it. Many trait impls are forwarded, so if you only needDisplay
then no changes will be necessary.If that code was conditionally compiled, you may instead want to use the methods on
TrackLocationOption
to remove the need for conditional compilation.