Struct Trigger

Source
pub struct Trigger<'w, E, B = ()>
where B: Bundle,
{ /* private fields */ }
Expand description

Type containing triggered Event information for a given run of an Observer. This contains the Event data itself. If it was triggered for a specific Entity, it includes that as well. It also contains event propagation information. See Trigger::propagate for more information.

Implementations§

Source§

impl<'w, E, B> Trigger<'w, E, B>
where B: Bundle,

Source

pub fn new( event: &'w mut E, propagate: &'w mut bool, trigger: ObserverTrigger, ) -> Trigger<'w, E, B>

Creates a new trigger for the given event and observer information.

Source

pub fn event_type(&self) -> ComponentId

Returns the event type of this trigger.

Source

pub fn event(&self) -> &E

Returns a reference to the triggered event.

Examples found in repository?
examples/animation/animation_events.rs (line 33)
28fn edit_message(
29    trigger: Trigger<MessageEvent>,
30    text: Single<(&mut Text2d, &mut TextColor), With<MessageText>>,
31) {
32    let (mut text, mut color) = text.into_inner();
33    text.0 = trigger.event().value.clone();
34    color.0 = trigger.event().color;
35}
More examples
Hide additional examples
examples/ecs/observer_propagation.rs (line 112)
106fn take_damage(
107    trigger: Trigger<Attack>,
108    mut hp: Query<(&mut HitPoints, &Name)>,
109    mut commands: Commands,
110    mut app_exit: EventWriter<AppExit>,
111) {
112    let attack = trigger.event();
113    let (mut hp, name) = hp.get_mut(trigger.target()).unwrap();
114    **hp = hp.saturating_sub(attack.damage);
115
116    if **hp > 0 {
117        info!("{} has {:.1} HP", name, hp.0);
118    } else {
119        warn!("💀 {} has died a gruesome death", name);
120        commands.entity(trigger.target()).despawn();
121        app_exit.write(AppExit::Success);
122    }
123
124    info!("(propagation reached root)\n");
125}
examples/ecs/observers.rs (line 24)
10fn main() {
11    App::new()
12        .add_plugins(DefaultPlugins)
13        .init_resource::<SpatialIndex>()
14        .add_systems(Startup, setup)
15        .add_systems(Update, (draw_shapes, handle_click))
16        // Observers are systems that run when an event is "triggered". This observer runs whenever
17        // `ExplodeMines` is triggered.
18        .add_observer(
19            |trigger: Trigger<ExplodeMines>,
20             mines: Query<&Mine>,
21             index: Res<SpatialIndex>,
22             mut commands: Commands| {
23                // You can access the trigger data via the `Observer`
24                let event = trigger.event();
25                // Access resources
26                for e in index.get_nearby(event.pos) {
27                    // Run queries
28                    let mine = mines.get(e).unwrap();
29                    if mine.pos.distance(event.pos) < mine.size + event.radius {
30                        // And queue commands, including triggering additional events
31                        // Here we trigger the `Explode` event for entity `e`
32                        commands.trigger_targets(Explode, e);
33                    }
34                }
35            },
36        )
37        // This observer runs whenever the `Mine` component is added to an entity, and places it in a simple spatial index.
38        .add_observer(on_add_mine)
39        // This observer runs whenever the `Mine` component is removed from an entity (including despawning it)
40        // and removes it from the spatial index.
41        .add_observer(on_remove_mine)
42        .run();
43}
examples/shader/gpu_readback.rs (line 109)
71fn setup(
72    mut commands: Commands,
73    mut images: ResMut<Assets<Image>>,
74    mut buffers: ResMut<Assets<ShaderStorageBuffer>>,
75) {
76    // Create a storage buffer with some data
77    let buffer = vec![0u32; BUFFER_LEN];
78    let mut buffer = ShaderStorageBuffer::from(buffer);
79    // We need to enable the COPY_SRC usage so we can copy the buffer to the cpu
80    buffer.buffer_description.usage |= BufferUsages::COPY_SRC;
81    let buffer = buffers.add(buffer);
82
83    // Create a storage texture with some data
84    let size = Extent3d {
85        width: BUFFER_LEN as u32,
86        height: 1,
87        ..default()
88    };
89    // We create an uninitialized image since this texture will only be used for getting data out
90    // of the compute shader, not getting data in, so there's no reason for it to exist on the CPU
91    let mut image = Image::new_uninit(
92        size,
93        TextureDimension::D2,
94        TextureFormat::R32Uint,
95        RenderAssetUsages::RENDER_WORLD,
96    );
97    // We also need to enable the COPY_SRC, as well as STORAGE_BINDING so we can use it in the
98    // compute shader
99    image.texture_descriptor.usage |= TextureUsages::COPY_SRC | TextureUsages::STORAGE_BINDING;
100    let image = images.add(image);
101
102    // Spawn the readback components. For each frame, the data will be read back from the GPU
103    // asynchronously and trigger the `ReadbackComplete` event on this entity. Despawn the entity
104    // to stop reading back the data.
105    commands.spawn(Readback::buffer(buffer.clone())).observe(
106        |trigger: Trigger<ReadbackComplete>| {
107            // This matches the type which was used to create the `ShaderStorageBuffer` above,
108            // and is a convenient way to interpret the data.
109            let data: Vec<u32> = trigger.event().to_shader_type();
110            info!("Buffer {:?}", data);
111        },
112    );
113    // This is just a simple way to pass the buffer handle to the render app for our compute node
114    commands.insert_resource(ReadbackBuffer(buffer));
115
116    // Textures can also be read back from the GPU. Pay careful attention to the format of the
117    // texture, as it will affect how the data is interpreted.
118    commands.spawn(Readback::texture(image.clone())).observe(
119        |trigger: Trigger<ReadbackComplete>| {
120            // You probably want to interpret the data as a color rather than a `ShaderType`,
121            // but in this case we know the data is a single channel storage texture, so we can
122            // interpret it as a `Vec<u32>`
123            let data: Vec<u32> = trigger.event().to_shader_type();
124            info!("Image {:?}", data);
125        },
126    );
127    commands.insert_resource(ReadbackImage(image));
128}
examples/ui/scroll.rs (line 95)
25fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
26    // Camera
27    commands.spawn((Camera2d, IsDefaultUiCamera));
28
29    // root node
30    commands
31        .spawn(Node {
32            width: Val::Percent(100.0),
33            height: Val::Percent(100.0),
34            justify_content: JustifyContent::SpaceBetween,
35            flex_direction: FlexDirection::Column,
36            ..default()
37        })
38        .insert(Pickable::IGNORE)
39        .with_children(|parent| {
40            // horizontal scroll example
41            parent
42                .spawn(Node {
43                    width: Val::Percent(100.),
44                    flex_direction: FlexDirection::Column,
45                    ..default()
46                })
47                .with_children(|parent| {
48                    // header
49                    parent.spawn((
50                        Text::new("Horizontally Scrolling list (Ctrl + MouseWheel)"),
51                        TextFont {
52                            font: asset_server.load("fonts/FiraSans-Bold.ttf"),
53                            font_size: FONT_SIZE,
54                            ..default()
55                        },
56                        Label,
57                    ));
58
59                    // horizontal scroll container
60                    parent
61                        .spawn((
62                            Node {
63                                width: Val::Percent(80.),
64                                margin: UiRect::all(Val::Px(10.)),
65                                flex_direction: FlexDirection::Row,
66                                overflow: Overflow::scroll_x(), // n.b.
67                                ..default()
68                            },
69                            BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
70                        ))
71                        .with_children(|parent| {
72                            for i in 0..100 {
73                                parent.spawn((Text(format!("Item {i}")),
74                                        TextFont {
75                                            font: asset_server
76                                                .load("fonts/FiraSans-Bold.ttf"),
77                                            ..default()
78                                        },
79                                    Label,
80                                    AccessibilityNode(Accessible::new(Role::ListItem)),
81                                ))
82                                .insert(Node {
83                                    min_width: Val::Px(200.),
84                                    align_content: AlignContent::Center,
85                                    ..default()
86                                })
87                                .insert(Pickable {
88                                    should_block_lower: false,
89                                    ..default()
90                                })
91                                .observe(|
92                                    trigger: Trigger<Pointer<Pressed>>,
93                                    mut commands: Commands
94                                | {
95                                    if trigger.event().button == PointerButton::Primary {
96                                        commands.entity(trigger.target()).despawn();
97                                    }
98                                });
99                            }
100                        });
101                });
102
103            // container for all other examples
104            parent
105                .spawn(Node {
106                    width: Val::Percent(100.),
107                    height: Val::Percent(100.),
108                    flex_direction: FlexDirection::Row,
109                    justify_content: JustifyContent::SpaceBetween,
110                    ..default()
111                })
112                .with_children(|parent| {
113                    // vertical scroll example
114                    parent
115                        .spawn(Node {
116                            flex_direction: FlexDirection::Column,
117                            justify_content: JustifyContent::Center,
118                            align_items: AlignItems::Center,
119                            width: Val::Px(200.),
120                            ..default()
121                        })
122                        .with_children(|parent| {
123                            // Title
124                            parent.spawn((
125                                Text::new("Vertically Scrolling List"),
126                                TextFont {
127                                    font: asset_server.load("fonts/FiraSans-Bold.ttf"),
128                                    font_size: FONT_SIZE,
129                                    ..default()
130                                },
131                                Label,
132                            ));
133                            // Scrolling list
134                            parent
135                                .spawn((
136                                    Node {
137                                        flex_direction: FlexDirection::Column,
138                                        align_self: AlignSelf::Stretch,
139                                        height: Val::Percent(50.),
140                                        overflow: Overflow::scroll_y(), // n.b.
141                                        ..default()
142                                    },
143                                    BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
144                                ))
145                                .with_children(|parent| {
146                                    // List items
147                                    for i in 0..25 {
148                                        parent
149                                            .spawn(Node {
150                                                min_height: Val::Px(LINE_HEIGHT),
151                                                max_height: Val::Px(LINE_HEIGHT),
152                                                ..default()
153                                            })
154                                            .insert(Pickable {
155                                                should_block_lower: false,
156                                                ..default()
157                                            })
158                                            .with_children(|parent| {
159                                                parent
160                                                    .spawn((
161                                                        Text(format!("Item {i}")),
162                                                        TextFont {
163                                                            font: asset_server
164                                                                .load("fonts/FiraSans-Bold.ttf"),
165                                                            ..default()
166                                                        },
167                                                        Label,
168                                                        AccessibilityNode(Accessible::new(
169                                                            Role::ListItem,
170                                                        )),
171                                                    ))
172                                                    .insert(Pickable {
173                                                        should_block_lower: false,
174                                                        ..default()
175                                                    });
176                                            });
177                                    }
178                                });
179                        });
180
181                    // Bidirectional scroll example
182                    parent
183                        .spawn(Node {
184                            flex_direction: FlexDirection::Column,
185                            justify_content: JustifyContent::Center,
186                            align_items: AlignItems::Center,
187                            width: Val::Px(200.),
188                            ..default()
189                        })
190                        .with_children(|parent| {
191                            // Title
192                            parent.spawn((
193                                Text::new("Bidirectionally Scrolling List"),
194                                TextFont {
195                                    font: asset_server.load("fonts/FiraSans-Bold.ttf"),
196                                    font_size: FONT_SIZE,
197                                    ..default()
198                                },
199                                Label,
200                            ));
201                            // Scrolling list
202                            parent
203                                .spawn((
204                                    Node {
205                                        flex_direction: FlexDirection::Column,
206                                        align_self: AlignSelf::Stretch,
207                                        height: Val::Percent(50.),
208                                        overflow: Overflow::scroll(), // n.b.
209                                        ..default()
210                                    },
211                                    BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
212                                ))
213                                .with_children(|parent| {
214                                    // Rows in each column
215                                    for oi in 0..10 {
216                                        parent
217                                            .spawn(Node {
218                                                flex_direction: FlexDirection::Row,
219                                                ..default()
220                                            })
221                                            .insert(Pickable::IGNORE)
222                                            .with_children(|parent| {
223                                                // Elements in each row
224                                                for i in 0..25 {
225                                                    parent
226                                                        .spawn((
227                                                            Text(format!("Item {}", (oi * 25) + i)),
228                                                            TextFont {
229                                                                font: asset_server.load(
230                                                                    "fonts/FiraSans-Bold.ttf",
231                                                                ),
232                                                                ..default()
233                                                            },
234                                                            Label,
235                                                            AccessibilityNode(Accessible::new(
236                                                                Role::ListItem,
237                                                            )),
238                                                        ))
239                                                        .insert(Pickable {
240                                                            should_block_lower: false,
241                                                            ..default()
242                                                        });
243                                                }
244                                            });
245                                    }
246                                });
247                        });
248
249                    // Nested scrolls example
250                    parent
251                        .spawn(Node {
252                            flex_direction: FlexDirection::Column,
253                            justify_content: JustifyContent::Center,
254                            align_items: AlignItems::Center,
255                            width: Val::Px(200.),
256                            ..default()
257                        })
258                        .with_children(|parent| {
259                            // Title
260                            parent.spawn((
261                                Text::new("Nested Scrolling Lists"),
262                                TextFont {
263                                    font: asset_server.load("fonts/FiraSans-Bold.ttf"),
264                                    font_size: FONT_SIZE,
265                                    ..default()
266                                },
267                                Label,
268                            ));
269                            // Outer, horizontal scrolling container
270                            parent
271                                .spawn((
272                                    Node {
273                                        column_gap: Val::Px(20.),
274                                        flex_direction: FlexDirection::Row,
275                                        align_self: AlignSelf::Stretch,
276                                        height: Val::Percent(50.),
277                                        overflow: Overflow::scroll_x(), // n.b.
278                                        ..default()
279                                    },
280                                    BackgroundColor(Color::srgb(0.10, 0.10, 0.10)),
281                                ))
282                                .with_children(|parent| {
283                                    // Inner, scrolling columns
284                                    for oi in 0..30 {
285                                        parent
286                                            .spawn((
287                                                Node {
288                                                    flex_direction: FlexDirection::Column,
289                                                    align_self: AlignSelf::Stretch,
290                                                    overflow: Overflow::scroll_y(),
291                                                    ..default()
292                                                },
293                                                BackgroundColor(Color::srgb(0.05, 0.05, 0.05)),
294                                            ))
295                                            .insert(Pickable {
296                                                should_block_lower: false,
297                                                ..default()
298                                            })
299                                            .with_children(|parent| {
300                                                for i in 0..25 {
301                                                    parent
302                                                        .spawn((
303                                                            Text(format!("Item {}", (oi * 25) + i)),
304                                                            TextFont {
305                                                                font: asset_server.load(
306                                                                    "fonts/FiraSans-Bold.ttf",
307                                                                ),
308                                                                ..default()
309                                                            },
310                                                            Label,
311                                                            AccessibilityNode(Accessible::new(
312                                                                Role::ListItem,
313                                                            )),
314                                                        ))
315                                                        .insert(Pickable {
316                                                            should_block_lower: false,
317                                                            ..default()
318                                                        });
319                                                }
320                                            });
321                                    }
322                                });
323                        });
324                });
325        });
326}
Source

pub fn event_mut(&mut self) -> &mut E

Returns a mutable reference to the triggered event.

Examples found in repository?
examples/ecs/observer_propagation.rs (line 89)
87fn block_attack(mut trigger: Trigger<Attack>, armor: Query<(&Armor, &Name)>) {
88    let (armor, name) = armor.get(trigger.target()).unwrap();
89    let attack = trigger.event_mut();
90    let damage = attack.damage.saturating_sub(**armor);
91    if damage > 0 {
92        info!("🩸 {} damage passed through {}", damage, name);
93        // The attack isn't stopped by the armor. We reduce the damage of the attack, and allow
94        // it to continue on to the goblin.
95        attack.damage = damage;
96    } else {
97        info!("🛡️  {} damage blocked by {}", attack.damage, name);
98        // Armor stopped the attack, the event stops here.
99        trigger.propagate(false);
100        info!("(propagation halted early)\n");
101    }
102}
Source

pub fn event_ptr(&self) -> Ptr<'_>

Returns a pointer to the triggered event.

Source

pub fn target(&self) -> Entity

Returns the Entity that was targeted by the event that triggered this observer. It may be Entity::PLACEHOLDER.

Observable events can target specific entities. When those events fire, they will trigger any observers on the targeted entities. In this case, the target() and observer() are the same, because the observer that was triggered is attached to the entity that was targeted by the event.

However, it is also possible for those events to bubble up the entity hierarchy and trigger observers on different entities, or trigger a global observer. In these cases, the observing entity is different from the entity being targeted by the event.

This is an important distinction: the entity reacting to an event is not always the same as the entity triggered by the event.

Examples found in repository?
examples/ecs/observer_propagation.rs (line 81)
80fn attack_hits(trigger: Trigger<Attack>, name: Query<&Name>) {
81    if let Ok(name) = name.get(trigger.target()) {
82        info!("Attack hit {}", name);
83    }
84}
85
86/// A callback placed on [`Armor`], checking if it absorbed all the [`Attack`] damage.
87fn block_attack(mut trigger: Trigger<Attack>, armor: Query<(&Armor, &Name)>) {
88    let (armor, name) = armor.get(trigger.target()).unwrap();
89    let attack = trigger.event_mut();
90    let damage = attack.damage.saturating_sub(**armor);
91    if damage > 0 {
92        info!("🩸 {} damage passed through {}", damage, name);
93        // The attack isn't stopped by the armor. We reduce the damage of the attack, and allow
94        // it to continue on to the goblin.
95        attack.damage = damage;
96    } else {
97        info!("🛡️  {} damage blocked by {}", attack.damage, name);
98        // Armor stopped the attack, the event stops here.
99        trigger.propagate(false);
100        info!("(propagation halted early)\n");
101    }
102}
103
104/// A callback on the armor wearer, triggered when a piece of armor is not able to block an attack,
105/// or the wearer is attacked directly.
106fn take_damage(
107    trigger: Trigger<Attack>,
108    mut hp: Query<(&mut HitPoints, &Name)>,
109    mut commands: Commands,
110    mut app_exit: EventWriter<AppExit>,
111) {
112    let attack = trigger.event();
113    let (mut hp, name) = hp.get_mut(trigger.target()).unwrap();
114    **hp = hp.saturating_sub(attack.damage);
115
116    if **hp > 0 {
117        info!("{} has {:.1} HP", name, hp.0);
118    } else {
119        warn!("💀 {} has died a gruesome death", name);
120        commands.entity(trigger.target()).despawn();
121        app_exit.write(AppExit::Success);
122    }
123
124    info!("(propagation reached root)\n");
125}
More examples
Hide additional examples
examples/picking/sprite_picking.rs (line 156)
154fn recolor_on<E: Debug + Clone + Reflect>(color: Color) -> impl Fn(Trigger<E>, Query<&mut Sprite>) {
155    move |ev, mut sprites| {
156        let Ok(mut sprite) = sprites.get_mut(ev.target()) else {
157            return;
158        };
159        sprite.color = color;
160    }
161}
examples/ecs/removal_detection.rs (line 53)
51fn react_on_removal(trigger: Trigger<OnRemove, MyComponent>, mut query: Query<&mut Sprite>) {
52    // The `OnRemove` trigger was automatically called on the `Entity` that had its `MyComponent` removed.
53    let entity = trigger.target();
54    if let Ok(mut sprite) = query.get_mut(entity) {
55        sprite.color = Color::srgb(0.5, 1., 1.);
56    }
57}
examples/ecs/observers.rs (line 120)
115fn on_add_mine(
116    trigger: Trigger<OnAdd, Mine>,
117    query: Query<&Mine>,
118    mut index: ResMut<SpatialIndex>,
119) {
120    let mine = query.get(trigger.target()).unwrap();
121    let tile = (
122        (mine.pos.x / CELL_SIZE).floor() as i32,
123        (mine.pos.y / CELL_SIZE).floor() as i32,
124    );
125    index.map.entry(tile).or_default().insert(trigger.target());
126}
127
128// Remove despawned mines from our index
129fn on_remove_mine(
130    trigger: Trigger<OnRemove, Mine>,
131    query: Query<&Mine>,
132    mut index: ResMut<SpatialIndex>,
133) {
134    let mine = query.get(trigger.target()).unwrap();
135    let tile = (
136        (mine.pos.x / CELL_SIZE).floor() as i32,
137        (mine.pos.y / CELL_SIZE).floor() as i32,
138    );
139    index.map.entry(tile).and_modify(|set| {
140        set.remove(&trigger.target());
141    });
142}
143
144fn explode_mine(trigger: Trigger<Explode>, query: Query<&Mine>, mut commands: Commands) {
145    // If a triggered event is targeting a specific entity you can access it with `.target()`
146    let id = trigger.target();
147    let Ok(mut entity) = commands.get_entity(id) else {
148        return;
149    };
150    info!("Boom! {} exploded.", id.index());
151    entity.despawn();
152    let mine = query.get(id).unwrap();
153    // Trigger another explosion cascade.
154    commands.trigger(ExplodeMines {
155        pos: mine.pos,
156        radius: mine.size,
157    });
158}
examples/picking/mesh_picking.rs (line 167)
160fn update_material_on<E>(
161    new_material: Handle<StandardMaterial>,
162) -> impl Fn(Trigger<E>, Query<&mut MeshMaterial3d<StandardMaterial>>) {
163    // An observer closure that captures `new_material`. We do this to avoid needing to write four
164    // versions of this observer, each triggered by a different event and with a different hardcoded
165    // material. Instead, the event type is a generic, and the material is passed in.
166    move |trigger, mut query| {
167        if let Ok(mut material) = query.get_mut(trigger.target()) {
168            material.0 = new_material.clone();
169        }
170    }
171}
172
173/// A system that draws hit indicators for every pointer.
174fn draw_mesh_intersections(pointers: Query<&PointerInteraction>, mut gizmos: Gizmos) {
175    for (point, normal) in pointers
176        .iter()
177        .filter_map(|interaction| interaction.get_nearest_hit())
178        .filter_map(|(_entity, hit)| hit.position.zip(hit.normal))
179    {
180        gizmos.sphere(point, 0.05, RED_500);
181        gizmos.arrow(point, point + normal.normalize() * 0.5, PINK_100);
182    }
183}
184
185/// A system that rotates all shapes.
186fn rotate(mut query: Query<&mut Transform, With<Shape>>, time: Res<Time>) {
187    for mut transform in &mut query {
188        transform.rotate_y(time.delta_secs() / 2.);
189    }
190}
191
192/// An observer to rotate an entity when it is dragged
193fn rotate_on_drag(drag: Trigger<Pointer<Drag>>, mut transforms: Query<&mut Transform>) {
194    let mut transform = transforms.get_mut(drag.target()).unwrap();
195    transform.rotate_y(drag.delta.x * 0.02);
196    transform.rotate_x(drag.delta.y * 0.02);
197}
examples/ui/directional_navigation.rs (line 73)
69fn universal_button_click_behavior(
70    mut trigger: Trigger<Pointer<Click>>,
71    mut button_query: Query<(&mut BackgroundColor, &mut ResetTimer)>,
72) {
73    let button_entity = trigger.target();
74    if let Ok((mut color, mut reset_timer)) = button_query.get_mut(button_entity) {
75        // This would be a great place to play a little sound effect too!
76        color.0 = PRESSED_BUTTON.into();
77        reset_timer.0 = Timer::from_seconds(0.3, TimerMode::Once);
78
79        // Picking events propagate up the hierarchy,
80        // so we need to stop the propagation here now that we've handled it
81        trigger.propagate(false);
82    }
83}
Source

pub fn components(&self) -> &[ComponentId]

Returns the components that triggered the observer, out of the components defined in B. Does not necessarily include all of them as B acts like an OR filter rather than an AND filter.

Source

pub fn observer(&self) -> Entity

Returns the Entity that observed the triggered event. This allows you to despawn the observer, ceasing observation.

§Examples
/// Handle `MyEvent` and if it is done, stop observation.
fn my_observer(trigger: Trigger<MyEvent>, mut commands: Commands) {
    if trigger.event().done {
        commands.entity(trigger.observer()).despawn();
        return;
    }

    // ...
}
Source

pub fn propagate(&mut self, should_propagate: bool)

Enables or disables event propagation, allowing the same event to trigger observers on a chain of different entities.

The path an event will propagate along is specified by its associated Traversal component. By default, events use () which ends the path immediately and prevents propagation.

To enable propagation, you must:

You can prevent an event from propagating further using propagate(false).

Examples found in repository?
examples/ui/directional_navigation.rs (line 81)
69fn universal_button_click_behavior(
70    mut trigger: Trigger<Pointer<Click>>,
71    mut button_query: Query<(&mut BackgroundColor, &mut ResetTimer)>,
72) {
73    let button_entity = trigger.target();
74    if let Ok((mut color, mut reset_timer)) = button_query.get_mut(button_entity) {
75        // This would be a great place to play a little sound effect too!
76        color.0 = PRESSED_BUTTON.into();
77        reset_timer.0 = Timer::from_seconds(0.3, TimerMode::Once);
78
79        // Picking events propagate up the hierarchy,
80        // so we need to stop the propagation here now that we've handled it
81        trigger.propagate(false);
82    }
83}
More examples
Hide additional examples
examples/ecs/observer_propagation.rs (line 99)
87fn block_attack(mut trigger: Trigger<Attack>, armor: Query<(&Armor, &Name)>) {
88    let (armor, name) = armor.get(trigger.target()).unwrap();
89    let attack = trigger.event_mut();
90    let damage = attack.damage.saturating_sub(**armor);
91    if damage > 0 {
92        info!("🩸 {} damage passed through {}", damage, name);
93        // The attack isn't stopped by the armor. We reduce the damage of the attack, and allow
94        // it to continue on to the goblin.
95        attack.damage = damage;
96    } else {
97        info!("🛡️  {} damage blocked by {}", attack.damage, name);
98        // Armor stopped the attack, the event stops here.
99        trigger.propagate(false);
100        info!("(propagation halted early)\n");
101    }
102}
examples/ui/tab_navigation.rs (line 97)
81fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
82    // ui camera
83    commands.spawn(Camera2d);
84    commands
85        .spawn(Node {
86            width: Val::Percent(100.0),
87            height: Val::Percent(100.0),
88            display: Display::Flex,
89            flex_direction: FlexDirection::Column,
90            align_items: AlignItems::Center,
91            justify_content: JustifyContent::Center,
92            ..default()
93        })
94        .observe(
95            |mut trigger: Trigger<Pointer<Click>>, mut focus: ResMut<InputFocus>| {
96                focus.0 = None;
97                trigger.propagate(false);
98            },
99        )
100        .with_children(|parent| {
101            parent.spawn(Text::new("Tab Group 0"));
102            parent
103                .spawn((
104                    Node {
105                        display: Display::Flex,
106                        flex_direction: FlexDirection::Row,
107                        column_gap: Val::Px(6.0),
108                        margin: UiRect {
109                            bottom: Val::Px(10.0),
110                            ..default()
111                        },
112                        ..default()
113                    },
114                    TabGroup::new(0),
115                ))
116                .with_children(|parent| {
117                    create_button(parent, &asset_server);
118                    create_button(parent, &asset_server);
119                    create_button(parent, &asset_server);
120                    create_button(parent, &asset_server);
121                });
122
123            parent.spawn(Text::new("Tab Group 2"));
124            parent
125                .spawn((
126                    Node {
127                        display: Display::Flex,
128                        flex_direction: FlexDirection::Row,
129                        column_gap: Val::Px(6.0),
130                        margin: UiRect {
131                            bottom: Val::Px(10.0),
132                            ..default()
133                        },
134                        ..default()
135                    },
136                    TabGroup::new(2),
137                ))
138                .with_children(|parent| {
139                    create_button(parent, &asset_server);
140                    create_button(parent, &asset_server);
141                    create_button(parent, &asset_server);
142                    create_button(parent, &asset_server);
143                });
144
145            parent.spawn(Text::new("Tab Group 1"));
146            parent
147                .spawn((
148                    Node {
149                        display: Display::Flex,
150                        flex_direction: FlexDirection::Row,
151                        column_gap: Val::Px(6.0),
152                        margin: UiRect {
153                            bottom: Val::Px(10.0),
154                            ..default()
155                        },
156                        ..default()
157                    },
158                    TabGroup::new(1),
159                ))
160                .with_children(|parent| {
161                    create_button(parent, &asset_server);
162                    create_button(parent, &asset_server);
163                    create_button(parent, &asset_server);
164                    create_button(parent, &asset_server);
165                });
166
167            parent.spawn(Text::new("Modal Tab Group"));
168            parent
169                .spawn((
170                    Node {
171                        display: Display::Flex,
172                        flex_direction: FlexDirection::Row,
173                        column_gap: Val::Px(6.0),
174                        ..default()
175                    },
176                    TabGroup::modal(),
177                ))
178                .with_children(|parent| {
179                    create_button(parent, &asset_server);
180                    create_button(parent, &asset_server);
181                    create_button(parent, &asset_server);
182                    create_button(parent, &asset_server);
183                });
184        });
185}
186
187fn create_button(parent: &mut ChildSpawnerCommands<'_>, asset_server: &AssetServer) {
188    parent
189        .spawn((
190            Button,
191            Node {
192                width: Val::Px(150.0),
193                height: Val::Px(65.0),
194                border: UiRect::all(Val::Px(5.0)),
195                // horizontally center child text
196                justify_content: JustifyContent::Center,
197                // vertically center child text
198                align_items: AlignItems::Center,
199                ..default()
200            },
201            BorderColor(Color::BLACK),
202            BorderRadius::MAX,
203            BackgroundColor(NORMAL_BUTTON),
204            TabIndex(0),
205        ))
206        .observe(
207            |mut trigger: Trigger<Pointer<Click>>, mut focus: ResMut<InputFocus>| {
208                focus.0 = Some(trigger.target());
209                trigger.propagate(false);
210            },
211        )
212        .with_child((
213            Text::new("Button"),
214            TextFont {
215                font: asset_server.load("fonts/FiraSans-Bold.ttf"),
216                font_size: 23.0,
217                ..default()
218            },
219            TextColor(Color::srgb(0.9, 0.9, 0.9)),
220        ));
221}
Source

pub fn get_propagate(&self) -> bool

Returns the value of the flag that controls event propagation. See propagate for more information.

Source

pub fn caller(&self) -> MaybeLocation

Returns the source code location that triggered this observer.

Trait Implementations§

Source§

impl<'w, E, B> Debug for Trigger<'w, E, B>
where E: Debug, B: Bundle,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'w, E, B> Deref for Trigger<'w, E, B>
where B: Bundle,

Source§

type Target = E

The resulting type after dereferencing.
Source§

fn deref(&self) -> &<Trigger<'w, E, B> as Deref>::Target

Dereferences the value.
Source§

impl<'w, E, B> DerefMut for Trigger<'w, E, B>
where B: Bundle,

Source§

fn deref_mut(&mut self) -> &mut <Trigger<'w, E, B> as Deref>::Target

Mutably dereferences the value.
Source§

impl<E, B> SystemInput for Trigger<'_, E, B>
where E: 'static, B: Bundle,

Used for ObserverSystems.

Source§

type Param<'i> = Trigger<'i, E, B>

The wrapper input type that is defined as the first argument to FunctionSystems.
Source§

type Inner<'i> = Trigger<'i, E, B>

The inner input type that is passed to functions that run systems, such as System::run.
Source§

fn wrap( this: <Trigger<'_, E, B> as SystemInput>::Inner<'_>, ) -> <Trigger<'_, E, B> as SystemInput>::Param<'_>

Auto Trait Implementations§

§

impl<'w, E, B> Freeze for Trigger<'w, E, B>

§

impl<'w, E, B> RefUnwindSafe for Trigger<'w, E, B>

§

impl<'w, E, B> Send for Trigger<'w, E, B>
where E: Send,

§

impl<'w, E, B> Sync for Trigger<'w, E, B>
where E: Sync,

§

impl<'w, E, B> Unpin for Trigger<'w, E, B>
where B: Unpin,

§

impl<'w, E, B = ()> !UnwindSafe for Trigger<'w, E, B>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, U> AsBindGroupShaderType<U> for T
where U: ShaderType, &'a T: for<'a> Into<U>,

Source§

fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U

Return the T ShaderType for self. When used in AsBindGroup derives, it is safe to assume that all images in self exist.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T, C, D> Curve<T> for D
where C: Curve<T> + ?Sized, D: Deref<Target = C>,

Source§

fn domain(&self) -> Interval

The interval over which this curve is parametrized. Read more
Source§

fn sample_unchecked(&self, t: f32) -> T

Sample a point on this curve at the parameter value t, extracting the associated value. This is the unchecked version of sampling, which should only be used if the sample time t is already known to lie within the curve’s domain. Read more
Source§

fn sample(&self, t: f32) -> Option<T>

Sample a point on this curve at the parameter value t, returning None if the point is outside of the curve’s domain.
Source§

fn sample_clamped(&self, t: f32) -> T

Sample a point on this curve at the parameter value t, clamping t to lie inside the domain of the curve.
Source§

impl<C, T> CurveExt<T> for C
where C: Curve<T>,

Source§

fn sample_iter( &self, iter: impl IntoIterator<Item = f32>, ) -> impl Iterator<Item = Option<T>>

Sample a collection of n >= 0 points on this curve at the parameter values t_n, returning None if the point is outside of the curve’s domain. Read more
Source§

fn sample_iter_unchecked( &self, iter: impl IntoIterator<Item = f32>, ) -> impl Iterator<Item = T>

Sample a collection of n >= 0 points on this curve at the parameter values t_n, extracting the associated values. This is the unchecked version of sampling, which should only be used if the sample times t_n are already known to lie within the curve’s domain. Read more
Source§

fn sample_iter_clamped( &self, iter: impl IntoIterator<Item = f32>, ) -> impl Iterator<Item = T>

Sample a collection of n >= 0 points on this curve at the parameter values t_n, clamping t_n to lie inside the domain of the curve. Read more
Source§

fn map<S, F>(self, f: F) -> MapCurve<T, S, Self, F>
where F: Fn(T) -> S,

Create a new curve by mapping the values of this curve via a function f; i.e., if the sample at time t for this curve is x, the value at time t on the new curve will be f(x).
Source§

fn reparametrize<F>(self, domain: Interval, f: F) -> ReparamCurve<T, Self, F>
where F: Fn(f32) -> f32,

Create a new Curve whose parameter space is related to the parameter space of this curve by f. For each time t, the sample from the new curve at time t is the sample from this curve at time f(t). The given domain will be the domain of the new curve. The function f is expected to take domain into self.domain(). Read more
Source§

fn reparametrize_linear( self, domain: Interval, ) -> Result<LinearReparamCurve<T, Self>, LinearReparamError>

Linearly reparametrize this Curve, producing a new curve whose domain is the given domain instead of the current one. This operation is only valid for curves with bounded domains. Read more
Source§

fn reparametrize_by_curve<C>(self, other: C) -> CurveReparamCurve<T, Self, C>
where C: Curve<f32>,

Reparametrize this Curve by sampling from another curve. Read more
Source§

fn graph(self) -> GraphCurve<T, Self>

Create a new Curve which is the graph of this one; that is, its output echoes the sample time as part of a tuple. Read more
Source§

fn zip<S, C>( self, other: C, ) -> Result<ZipCurve<T, S, Self, C>, InvalidIntervalError>
where C: Curve<S>,

Create a new Curve by zipping this curve together with another. Read more
Source§

fn chain<C>(self, other: C) -> Result<ChainCurve<T, Self, C>, ChainError>
where C: Curve<T>,

Create a new Curve by composing this curve end-to-start with another, producing another curve with outputs of the same type. The domain of the other curve is translated so that its start coincides with where this curve ends. Read more
Source§

fn reverse(self) -> Result<ReverseCurve<T, Self>, ReverseError>

Create a new Curve inverting this curve on the x-axis, producing another curve with outputs of the same type, effectively playing backwards starting at self.domain().end() and transitioning over to self.domain().start(). The domain of the new curve is still the same. Read more
Source§

fn repeat(self, count: usize) -> Result<RepeatCurve<T, Self>, RepeatError>

Create a new Curve repeating this curve N times, producing another curve with outputs of the same type. The domain of the new curve will be bigger by a factor of n + 1. Read more
Source§

fn forever(self) -> Result<ForeverCurve<T, Self>, RepeatError>

Create a new Curve repeating this curve forever, producing another curve with outputs of the same type. The domain of the new curve will be unbounded. Read more
Source§

fn ping_pong(self) -> Result<PingPongCurve<T, Self>, PingPongError>

Create a new Curve chaining the original curve with its inverse, producing another curve with outputs of the same type. The domain of the new curve will be twice as long. The transition point is guaranteed to not make any jumps. Read more
Source§

fn chain_continue<C>( self, other: C, ) -> Result<ContinuationCurve<T, Self, C>, ChainError>
where T: VectorSpace, C: Curve<T>,

Create a new Curve by composing this curve end-to-start with another, producing another curve with outputs of the same type. The domain of the other curve is translated so that its start coincides with where this curve ends. Read more
Source§

fn samples( &self, samples: usize, ) -> Result<impl Iterator<Item = T>, ResamplingError>

Extract an iterator over evenly-spaced samples from this curve. Read more
Source§

fn by_ref(&self) -> &Self

Borrow this curve rather than taking ownership of it. This is essentially an alias for a prefix &; the point is that intermediate operations can be performed while retaining access to the original curve. Read more
Source§

fn flip<U, V>(self) -> impl Curve<(V, U)>
where Self: CurveExt<(U, V)>,

Flip this curve so that its tuple output is arranged the other way.
Source§

impl<C, T> CurveResampleExt<T> for C
where C: Curve<T> + ?Sized,

Source§

fn resample<I>( &self, segments: usize, interpolation: I, ) -> Result<SampleCurve<T, I>, ResamplingError>
where I: Fn(&T, &T, f32) -> T,

Resample this Curve to produce a new one that is defined by interpolation over equally spaced sample values, using the provided interpolation to interpolate between adjacent samples. The curve is interpolated on segments segments between samples. For example, if segments is 1, only the start and end points of the curve are used as samples; if segments is 2, a sample at the midpoint is taken as well, and so on. Read more
Source§

fn resample_auto( &self, segments: usize, ) -> Result<SampleAutoCurve<T>, ResamplingError>

Resample this Curve to produce a new one that is defined by interpolation over equally spaced sample values, using automatic interpolation to interpolate between adjacent samples. The curve is interpolated on segments segments between samples. For example, if segments is 1, only the start and end points of the curve are used as samples; if segments is 2, a sample at the midpoint is taken as well, and so on. Read more
Source§

fn resample_uneven<I>( &self, sample_times: impl IntoIterator<Item = f32>, interpolation: I, ) -> Result<UnevenSampleCurve<T, I>, ResamplingError>
where I: Fn(&T, &T, f32) -> T,

Resample this Curve to produce a new one that is defined by interpolation over samples taken at a given set of times. The given interpolation is used to interpolate adjacent samples, and the sample_times are expected to contain at least two valid times within the curve’s domain interval. Read more
Source§

fn resample_uneven_auto( &self, sample_times: impl IntoIterator<Item = f32>, ) -> Result<UnevenSampleAutoCurve<T>, ResamplingError>

Resample this Curve to produce a new one that is defined by automatic interpolation over samples taken at the given set of times. The given sample_times are expected to contain at least two valid times within the curve’s domain interval. Read more
Source§

impl<T, C> CurveWithDerivative<T> for C
where T: HasTangent, C: SampleDerivative<T>,

Source§

fn with_derivative(self) -> SampleDerivativeWrapper<C>

This curve, but with its first derivative included in sampling. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
Source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, C, D> SampleDerivative<T> for D
where T: HasTangent, C: SampleDerivative<T> + ?Sized, D: Deref<Target = C>,

Source§

fn sample_with_derivative_unchecked(&self, t: f32) -> WithDerivative<T>

Sample this curve at the parameter value t, extracting the associated value in addition to its derivative. This is the unchecked version of sampling, which should only be used if the sample time t is already known to lie within the curve’s domain. Read more
Source§

fn sample_with_derivative(&self, t: f32) -> Option<WithDerivative<T>>

Sample this curve’s value and derivative at the parameter value t, returning None if the point is outside of the curve’s domain.
Source§

fn sample_with_derivative_clamped(&self, t: f32) -> WithDerivative<T>

Sample this curve’s value and derivative at the parameter value t, clamping t to lie inside the domain of the curve.
Source§

impl<T> Source for T
where T: Deref, <T as Deref>::Target: Source,

Source§

type Slice<'a> = <<T as Deref>::Target as Source>::Slice<'a> where T: 'a

A type this Source can be sliced into.
Source§

fn len(&self) -> usize

Length of the source
Source§

fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>
where Chunk: Chunk<'a>,

Read a chunk of bytes into an array. Returns None when reading out of bounds would occur. Read more
Source§

unsafe fn read_byte_unchecked(&self, offset: usize) -> u8

Read a byte without doing bounds checks. Read more
Source§

fn slice(&self, range: Range<usize>) -> Option<<T as Source>::Slice<'_>>

Get a slice of the source at given range. This is analogous to slice::get(range). Read more
Source§

unsafe fn slice_unchecked( &self, range: Range<usize>, ) -> <T as Source>::Slice<'_>

Get a slice of the source at given range. This is analogous to slice::get_unchecked(range). Read more
Source§

fn is_boundary(&self, index: usize) -> bool

Check if index is valid for this Source, that is: Read more
Source§

fn find_boundary(&self, index: usize) -> usize

For &str sources attempts to find the closest char boundary at which source can be sliced, starting from index. Read more
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ConditionalSend for T
where T: Send,

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> Settings for T
where T: 'static + Send + Sync,

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,