@@ -12,8 +12,6 @@ pub mod widget;
1212use bevy_derive:: { Deref , DerefMut } ;
1313use bevy_reflect:: Reflect ;
1414#[ cfg( feature = "bevy_text" ) ]
15- use bevy_text:: TextLayoutInfo ;
16- #[ cfg( feature = "bevy_text" ) ]
1715mod accessibility;
1816mod focus;
1917mod geometry;
@@ -40,8 +38,6 @@ pub mod prelude {
4038 } ;
4139}
4240
43- #[ cfg( feature = "bevy_text" ) ]
44- use crate :: widget:: TextFlags ;
4541use bevy_app:: prelude:: * ;
4642use bevy_ecs:: prelude:: * ;
4743use bevy_input:: InputSystem ;
@@ -81,6 +77,14 @@ impl Default for UiScale {
8177 }
8278}
8379
80+ // Marks systems that can be ambiguous with [`widget::text_system`] if the `bevy_text` feature is enabled.
81+ // See https://github.com/bevyengine/bevy/pull/11391 for more details.
82+ #[ derive( SystemSet , Debug , Hash , PartialEq , Eq , Clone ) ]
83+ struct AmbiguousWithTextSystem ;
84+
85+ #[ derive( SystemSet , Debug , Hash , PartialEq , Eq , Clone ) ]
86+ struct AmbiguousWithUpdateText2DLayout ;
87+
8488impl Plugin for UiPlugin {
8589 fn build ( & self , app : & mut App ) {
8690 app. init_resource :: < UiSurface > ( )
@@ -129,51 +133,6 @@ impl Plugin for UiPlugin {
129133 ui_focus_system. in_set ( UiSystem :: Focus ) . after ( InputSystem ) ,
130134 ) ;
131135
132- #[ cfg( feature = "bevy_text" ) ]
133- app. register_type :: < TextLayoutInfo > ( )
134- . register_type :: < TextFlags > ( ) ;
135- // add these systems to front because these must run before transform update systems
136- #[ cfg( feature = "bevy_text" ) ]
137- app. add_systems (
138- PostUpdate ,
139- (
140- widget:: measure_text_system
141- . before ( UiSystem :: Layout )
142- // Potential conflict: `Assets<Image>`
143- // In practice, they run independently since `bevy_render::camera_update_system`
144- // will only ever observe its own render target, and `widget::measure_text_system`
145- // will never modify a pre-existing `Image` asset.
146- . ambiguous_with ( bevy_render:: camera:: CameraUpdateSystem )
147- // Potential conflict: `Assets<Image>`
148- // Since both systems will only ever insert new [`Image`] assets,
149- // they will never observe each other's effects.
150- . ambiguous_with ( bevy_text:: update_text2d_layout)
151- // We assume Text is on disjoint UI entities to UiImage and UiTextureAtlasImage
152- // FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
153- . ambiguous_with ( widget:: update_image_content_size_system) ,
154- widget:: text_system
155- . after ( UiSystem :: Layout )
156- . after ( bevy_text:: remove_dropped_font_atlas_sets)
157- // Text2d and bevy_ui text are entirely on separate entities
158- . ambiguous_with ( bevy_text:: update_text2d_layout) ,
159- ) ,
160- ) ;
161- #[ cfg( feature = "bevy_text" ) ]
162- app. add_plugins ( accessibility:: AccessibilityPlugin ) ;
163- app. add_systems ( PostUpdate , {
164- let system = widget:: update_image_content_size_system. before ( UiSystem :: Layout ) ;
165- // Potential conflicts: `Assets<Image>`
166- // They run independently since `widget::image_node_system` will only ever observe
167- // its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
168- // will never modify a pre-existing `Image` asset.
169- #[ cfg( feature = "bevy_text" ) ]
170- let system = system
171- . ambiguous_with ( bevy_text:: update_text2d_layout)
172- . ambiguous_with ( widget:: text_system) ;
173-
174- system
175- } ) ;
176-
177136 app. add_systems (
178137 PostUpdate ,
179138 (
@@ -189,18 +148,29 @@ impl Plugin for UiPlugin {
189148 . after ( UiSystem :: Layout )
190149 // clipping doesn't care about outlines
191150 . ambiguous_with ( update_clipping_system)
192- . ambiguous_with ( widget :: text_system ) ,
151+ . in_set ( AmbiguousWithTextSystem ) ,
193152 ui_stack_system
194153 . in_set ( UiSystem :: Stack )
195154 // the systems don't care about stack index
196155 . ambiguous_with ( update_clipping_system)
197156 . ambiguous_with ( resolve_outlines_system)
198157 . ambiguous_with ( ui_layout_system)
199- . ambiguous_with ( widget :: text_system ) ,
158+ . in_set ( AmbiguousWithTextSystem ) ,
200159 update_clipping_system. after ( TransformSystem :: TransformPropagate ) ,
160+ // Potential conflicts: `Assets<Image>`
161+ // They run independently since `widget::image_node_system` will only ever observe
162+ // its own UiImage, and `widget::text_system` & `bevy_text::update_text2d_layout`
163+ // will never modify a pre-existing `Image` asset.
164+ widget:: update_image_content_size_system
165+ . before ( UiSystem :: Layout )
166+ . in_set ( AmbiguousWithTextSystem )
167+ . in_set ( AmbiguousWithUpdateText2DLayout ) ,
201168 ) ,
202169 ) ;
203170
171+ #[ cfg( feature = "bevy_text" ) ]
172+ build_text_interop ( app) ;
173+
204174 build_ui_render ( app) ;
205175 }
206176
@@ -212,3 +182,50 @@ impl Plugin for UiPlugin {
212182 render_app. init_resource :: < UiPipeline > ( ) ;
213183 }
214184}
185+
186+ /// A function that should be called from [`UiPlugin::build`] when [`bevy_text`] is enabled.
187+ #[ cfg( feature = "bevy_text" ) ]
188+ fn build_text_interop ( app : & mut App ) {
189+ use crate :: widget:: TextFlags ;
190+ use bevy_text:: TextLayoutInfo ;
191+
192+ app. register_type :: < TextLayoutInfo > ( )
193+ . register_type :: < TextFlags > ( ) ;
194+
195+ app. add_systems (
196+ PostUpdate ,
197+ (
198+ widget:: measure_text_system
199+ . before ( UiSystem :: Layout )
200+ // Potential conflict: `Assets<Image>`
201+ // In practice, they run independently since `bevy_render::camera_update_system`
202+ // will only ever observe its own render target, and `widget::measure_text_system`
203+ // will never modify a pre-existing `Image` asset.
204+ . ambiguous_with ( bevy_render:: camera:: CameraUpdateSystem )
205+ // Potential conflict: `Assets<Image>`
206+ // Since both systems will only ever insert new [`Image`] assets,
207+ // they will never observe each other's effects.
208+ . ambiguous_with ( bevy_text:: update_text2d_layout)
209+ // We assume Text is on disjoint UI entities to UiImage and UiTextureAtlasImage
210+ // FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481.
211+ . ambiguous_with ( widget:: update_image_content_size_system) ,
212+ widget:: text_system
213+ . after ( UiSystem :: Layout )
214+ . after ( bevy_text:: remove_dropped_font_atlas_sets)
215+ // Text2d and bevy_ui text are entirely on separate entities
216+ . ambiguous_with ( bevy_text:: update_text2d_layout) ,
217+ ) ,
218+ ) ;
219+
220+ app. add_plugins ( accessibility:: AccessibilityPlugin ) ;
221+
222+ app. configure_sets (
223+ PostUpdate ,
224+ AmbiguousWithTextSystem . ambiguous_with ( widget:: text_system) ,
225+ ) ;
226+
227+ app. configure_sets (
228+ PostUpdate ,
229+ AmbiguousWithUpdateText2DLayout . ambiguous_with ( bevy_text:: update_text2d_layout) ,
230+ ) ;
231+ }
0 commit comments