pub struct HashMap<K, V, S = FixedHasher>(/* private fields */);
Expand description
New-type for HashMap
with FixedHasher
as the default hashing provider.
Can be trivially converted to and from a hashbrown HashMap
using From
.
A new-type is used instead of a type alias due to critical methods like new
being incompatible with Bevy’s choice of default hasher.
Unlike hashbrown::HashMap
, HashMap
defaults to FixedHasher
instead of RandomState
.
This provides determinism by default with an acceptable compromise to denial
of service resistance in the context of a game engine.
Implementations§
Source§impl<K, V> HashMap<K, V>
impl<K, V> HashMap<K, V>
Sourcepub fn with_capacity(capacity: usize) -> HashMap<K, V>
pub fn with_capacity(capacity: usize) -> HashMap<K, V>
Creates an empty HashMap
with the specified capacity.
Refer to with_capacity
for further details.
§Examples
// Creates a HashMap with capacity for at least 5 entries.
let map = HashMap::with_capacity(5);
Source§impl<K, V, S> HashMap<K, V, S>
impl<K, V, S> HashMap<K, V, S>
Sourcepub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S>
pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S>
Creates an empty HashMap
which will use the given hash builder to hash
keys.
Refer to with_hasher
for further details.
§Examples
// Creates a HashMap with the provided hasher.
let map = HashMap::with_hasher(SomeHasher);
Sourcepub fn with_capacity_and_hasher(
capacity: usize,
hash_builder: S,
) -> HashMap<K, V, S>
pub fn with_capacity_and_hasher( capacity: usize, hash_builder: S, ) -> HashMap<K, V, S>
Creates an empty HashMap
with the specified capacity, using hash_builder
to hash the keys.
Refer to with_capacity_and_hasher
for further details.
§Examples
// Creates a HashMap with capacity for 5 entries and the provided hasher.
let map = HashMap::with_capacity_and_hasher(5, SomeHasher);
Sourcepub fn hasher(&self) -> &S
pub fn hasher(&self) -> &S
Returns a reference to the map’s BuildHasher
, or S
parameter.
Refer to hasher
for further details.
Sourcepub fn keys(&self) -> Keys<'_, K, V> ⓘ
pub fn keys(&self) -> Keys<'_, K, V> ⓘ
An iterator visiting all keys in arbitrary order.
The iterator element type is &'a K
.
Refer to keys
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for key in map.keys() {
// foo, bar, baz
// Note that the above order is not guaranteed
}
Examples found in repository?
25fn send_scroll_events(
26 mut mouse_wheel_reader: MessageReader<MouseWheel>,
27 hover_map: Res<HoverMap>,
28 keyboard_input: Res<ButtonInput<KeyCode>>,
29 mut commands: Commands,
30) {
31 for mouse_wheel in mouse_wheel_reader.read() {
32 let mut delta = -Vec2::new(mouse_wheel.x, mouse_wheel.y);
33
34 if mouse_wheel.unit == MouseScrollUnit::Line {
35 delta *= LINE_HEIGHT;
36 }
37
38 if keyboard_input.any_pressed([KeyCode::ControlLeft, KeyCode::ControlRight]) {
39 std::mem::swap(&mut delta.x, &mut delta.y);
40 }
41
42 for pointer_map in hover_map.values() {
43 for entity in pointer_map.keys().copied() {
44 commands.trigger(Scroll { entity, delta });
45 }
46 }
47 }
48}
Sourcepub fn values(&self) -> Values<'_, K, V> ⓘ
pub fn values(&self) -> Values<'_, K, V> ⓘ
An iterator visiting all values in arbitrary order.
The iterator element type is &'a V
.
Refer to values
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for key in map.values() {
// 0, 1, 2
// Note that the above order is not guaranteed
}
Examples found in repository?
More examples
25fn send_scroll_events(
26 mut mouse_wheel_reader: MessageReader<MouseWheel>,
27 hover_map: Res<HoverMap>,
28 keyboard_input: Res<ButtonInput<KeyCode>>,
29 mut commands: Commands,
30) {
31 for mouse_wheel in mouse_wheel_reader.read() {
32 let mut delta = -Vec2::new(mouse_wheel.x, mouse_wheel.y);
33
34 if mouse_wheel.unit == MouseScrollUnit::Line {
35 delta *= LINE_HEIGHT;
36 }
37
38 if keyboard_input.any_pressed([KeyCode::ControlLeft, KeyCode::ControlRight]) {
39 std::mem::swap(&mut delta.x, &mut delta.y);
40 }
41
42 for pointer_map in hover_map.values() {
43 for entity in pointer_map.keys().copied() {
44 commands.trigger(Scroll { entity, delta });
45 }
46 }
47 }
48}
Sourcepub fn values_mut(&mut self) -> ValuesMut<'_, K, V> ⓘ
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> ⓘ
An iterator visiting all values mutably in arbitrary order.
The iterator element type is &'a mut V
.
Refer to values
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for key in map.values_mut() {
// 0, 1, 2
// Note that the above order is not guaranteed
}
Sourcepub fn iter(&self) -> Iter<'_, K, V> ⓘ
pub fn iter(&self) -> Iter<'_, K, V> ⓘ
An iterator visiting all key-value pairs in arbitrary order.
The iterator element type is (&'a K, &'a V)
.
Refer to iter
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for (key, value) in map.iter() {
// ("foo", 0), ("bar", 1), ("baz", 2)
// Note that the above order is not guaranteed
}
Examples found in repository?
438pub fn update_scroll_position(
439 mut mouse_wheel_reader: MessageReader<MouseWheel>,
440 hover_map: Res<HoverMap>,
441 mut scrolled_node_query: Query<(&mut ScrollPosition, &ComputedNode), Without<Scrollbar>>,
442 keyboard_input: Res<ButtonInput<KeyCode>>,
443) {
444 for mouse_wheel in mouse_wheel_reader.read() {
445 let (mut dx, mut dy) = match mouse_wheel.unit {
446 MouseScrollUnit::Line => (mouse_wheel.x * 20., mouse_wheel.y * 20.),
447 MouseScrollUnit::Pixel => (mouse_wheel.x, mouse_wheel.y),
448 };
449
450 if keyboard_input.pressed(KeyCode::ShiftLeft) || keyboard_input.pressed(KeyCode::ShiftRight)
451 {
452 std::mem::swap(&mut dx, &mut dy);
453 }
454
455 for (_pointer, pointer_map) in hover_map.iter() {
456 for (entity, _hit) in pointer_map.iter() {
457 if let Ok((mut scroll_position, scroll_content)) =
458 scrolled_node_query.get_mut(*entity)
459 {
460 let visible_size = scroll_content.size();
461 let content_size = scroll_content.content_size();
462
463 let range = (content_size.y - visible_size.y).max(0.)
464 * scroll_content.inverse_scale_factor;
465
466 scroll_position.x -= dx;
467 scroll_position.y = (scroll_position.y - dy).clamp(0., range);
468 }
469 }
470 }
471 }
472}
Sourcepub fn iter_mut(&mut self) -> IterMut<'_, K, V> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> ⓘ
An iterator visiting all key-value pairs in arbitrary order,
with mutable references to the values.
The iterator element type is (&'a K, &'a mut V)
.
Refer to iter_mut
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for (key, value) in map.iter_mut() {
// ("foo", 0), ("bar", 1), ("baz", 2)
// Note that the above order is not guaranteed
}
Examples found in repository?
337fn update_color_grading_settings(
338 keys: Res<ButtonInput<KeyCode>>,
339 time: Res<Time>,
340 mut per_method_settings: ResMut<PerMethodSettings>,
341 tonemapping: Single<&Tonemapping>,
342 current_scene: Res<CurrentScene>,
343 mut selected_parameter: ResMut<SelectedParameter>,
344) {
345 let color_grading = per_method_settings.settings.get_mut(*tonemapping).unwrap();
346 let mut dt = time.delta_secs() * 0.25;
347 if keys.pressed(KeyCode::ArrowLeft) {
348 dt = -dt;
349 }
350
351 if keys.just_pressed(KeyCode::ArrowDown) {
352 selected_parameter.next();
353 }
354 if keys.just_pressed(KeyCode::ArrowUp) {
355 selected_parameter.prev();
356 }
357 if keys.pressed(KeyCode::ArrowLeft) || keys.pressed(KeyCode::ArrowRight) {
358 match selected_parameter.value {
359 0 => {
360 color_grading.global.exposure += dt;
361 }
362 1 => {
363 color_grading
364 .all_sections_mut()
365 .for_each(|section| section.gamma += dt);
366 }
367 2 => {
368 color_grading
369 .all_sections_mut()
370 .for_each(|section| section.saturation += dt);
371 }
372 3 => {
373 color_grading.global.post_saturation += dt;
374 }
375 _ => {}
376 }
377 }
378
379 if keys.just_pressed(KeyCode::Space) {
380 for (_, grading) in per_method_settings.settings.iter_mut() {
381 *grading = ColorGrading::default();
382 }
383 }
384
385 if keys.just_pressed(KeyCode::Enter) && current_scene.0 == 1 {
386 for (mapper, grading) in per_method_settings.settings.iter_mut() {
387 *grading = PerMethodSettings::basic_scene_recommendation(*mapper);
388 }
389 }
390}
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of elements in the map.
Refer to len
for further details.
§Examples
let mut map = HashMap::new();
assert_eq!(map.len(), 0);
map.insert("foo", 0);
assert_eq!(map.len(), 1);
Examples found in repository?
166fn print_visible_light_count(
167 time: Res<Time>,
168 mut timer: Local<PrintingTimer>,
169 visible: Query<&ExtractedPointLight>,
170 global_light_meta: Res<GlobalClusterableObjectMeta>,
171) {
172 timer.0.tick(time.delta());
173
174 if timer.0.just_finished() {
175 info!(
176 "Visible Lights: {}, Rendered Lights: {}",
177 visible.iter().len(),
178 global_light_meta.entity_to_index.len()
179 );
180 }
181}
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the map contains no elements.
Refer to is_empty
for further details.
§Examples
let mut map = HashMap::new();
assert!(map.is_empty());
map.insert("foo", 0);
assert!(!map.is_empty());
Examples found in repository?
377pub fn queue_colored_mesh2d(
378 transparent_draw_functions: Res<DrawFunctions<Transparent2d>>,
379 colored_mesh2d_pipeline: Res<ColoredMesh2dPipeline>,
380 mut pipelines: ResMut<SpecializedRenderPipelines<ColoredMesh2dPipeline>>,
381 pipeline_cache: Res<PipelineCache>,
382 render_meshes: Res<RenderAssets<RenderMesh>>,
383 render_mesh_instances: Res<RenderColoredMesh2dInstances>,
384 mut transparent_render_phases: ResMut<ViewSortedRenderPhases<Transparent2d>>,
385 views: Query<(&RenderVisibleEntities, &ExtractedView, &Msaa)>,
386) {
387 if render_mesh_instances.is_empty() {
388 return;
389 }
390 // Iterate each view (a camera is a view)
391 for (visible_entities, view, msaa) in &views {
392 let Some(transparent_phase) = transparent_render_phases.get_mut(&view.retained_view_entity)
393 else {
394 continue;
395 };
396
397 let draw_colored_mesh2d = transparent_draw_functions.read().id::<DrawColoredMesh2d>();
398
399 let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples())
400 | Mesh2dPipelineKey::from_hdr(view.hdr);
401
402 // Queue all entities visible to that view
403 for (render_entity, visible_entity) in visible_entities.iter::<Mesh2d>() {
404 if let Some(mesh_instance) = render_mesh_instances.get(visible_entity) {
405 let mesh2d_handle = mesh_instance.mesh_asset_id;
406 let mesh2d_transforms = &mesh_instance.transforms;
407 // Get our specialized pipeline
408 let mut mesh2d_key = mesh_key;
409 let Some(mesh) = render_meshes.get(mesh2d_handle) else {
410 continue;
411 };
412 mesh2d_key |= Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology());
413
414 let pipeline_id =
415 pipelines.specialize(&pipeline_cache, &colored_mesh2d_pipeline, mesh2d_key);
416
417 let mesh_z = mesh2d_transforms.world_from_local.translation.z;
418 transparent_phase.add(Transparent2d {
419 entity: (*render_entity, *visible_entity),
420 draw_function: draw_colored_mesh2d,
421 pipeline: pipeline_id,
422 // The 2d render items are sorted according to their z value before rendering,
423 // in order to get correct transparency
424 sort_key: FloatOrd(mesh_z),
425 // This material is not batched
426 batch_range: 0..1,
427 extra_index: PhaseItemExtraIndex::None,
428 extracted_index: usize::MAX,
429 indexed: mesh.indexed(),
430 });
431 }
432 }
433 }
434}
Sourcepub fn drain(&mut self) -> Drain<'_, K, V> ⓘ
pub fn drain(&mut self) -> Drain<'_, K, V> ⓘ
Clears the map, returning all key-value pairs as an iterator. Keeps the allocated memory for reuse.
Refer to drain
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for (key, value) in map.drain() {
// ("foo", 0), ("bar", 1), ("baz", 2)
// Note that the above order is not guaranteed
}
assert!(map.is_empty());
Sourcepub fn retain<F>(&mut self, f: F)
pub fn retain<F>(&mut self, f: F)
Retains only the elements specified by the predicate. Keeps the allocated memory for reuse.
Refer to retain
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
map.retain(|key, value| *value == 2);
assert_eq!(map.len(), 1);
Examples found in repository?
472fn extract_camera_phases(
473 mut stencil_phases: ResMut<ViewSortedRenderPhases<Stencil3d>>,
474 cameras: Extract<Query<(Entity, &Camera), With<Camera3d>>>,
475 mut live_entities: Local<HashSet<RetainedViewEntity>>,
476) {
477 live_entities.clear();
478 for (main_entity, camera) in &cameras {
479 if !camera.is_active {
480 continue;
481 }
482 // This is the main camera, so we use the first subview index (0)
483 let retained_view_entity = RetainedViewEntity::new(main_entity.into(), None, 0);
484
485 stencil_phases.insert_or_clear(retained_view_entity);
486 live_entities.insert(retained_view_entity);
487 }
488
489 // Clear out all dead views.
490 stencil_phases.retain(|camera_entity, _| live_entities.contains(camera_entity));
491}
Sourcepub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F> ⓘ
pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F> ⓘ
Drains elements which are true under the given predicate, and returns an iterator over the removed items.
Refer to extract_if
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
let extracted = map
.extract_if(|key, value| *value == 2)
.collect::<Vec<_>>();
assert_eq!(map.len(), 2);
assert_eq!(extracted.len(), 1);
Sourcepub fn into_keys(self) -> IntoKeys<K, V> ⓘ
pub fn into_keys(self) -> IntoKeys<K, V> ⓘ
Creates a consuming iterator visiting all the keys in arbitrary order.
The map cannot be used after calling this.
The iterator element type is K
.
Refer to into_keys
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for key in map.into_keys() {
// "foo", "bar", "baz"
// Note that the above order is not guaranteed
}
Sourcepub fn into_values(self) -> IntoValues<K, V> ⓘ
pub fn into_values(self) -> IntoValues<K, V> ⓘ
Creates a consuming iterator visiting all the values in arbitrary order.
The map cannot be used after calling this.
The iterator element type is V
.
Refer to into_values
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
for key in map.into_values() {
// 0, 1, 2
// Note that the above order is not guaranteed
}
Sourcepub fn into_inner(self) -> HashMap<K, V, S>
pub fn into_inner(self) -> HashMap<K, V, S>
Source§impl<K, V, S> HashMap<K, V, S>
impl<K, V, S> HashMap<K, V, S>
Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Reserves capacity for at least additional
more elements to be inserted
in the HashMap
. The collection may reserve more space to avoid
frequent reallocations.
Refer to reserve
for further details.
§Examples
let mut map = HashMap::with_capacity(5);
assert!(map.capacity() >= 5);
map.reserve(10);
assert!(map.capacity() - map.len() >= 10);
Sourcepub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
Tries to reserve capacity for at least additional
more elements to be inserted
in the given HashMap<K,V>
. The collection may reserve more space to avoid
frequent reallocations.
Refer to try_reserve
for further details.
§Examples
let mut map = HashMap::with_capacity(5);
assert!(map.capacity() >= 5);
map.try_reserve(10).expect("Out of Memory!");
assert!(map.capacity() - map.len() >= 10);
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Shrinks the capacity of the map as much as possible. It will drop down as much as possible while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
Refer to shrink_to_fit
for further details.
§Examples
let mut map = HashMap::with_capacity(5);
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
assert!(map.capacity() >= 5);
map.shrink_to_fit();
assert_eq!(map.capacity(), 3);
Sourcepub fn shrink_to(&mut self, min_capacity: usize)
pub fn shrink_to(&mut self, min_capacity: usize)
Shrinks the capacity of the map with a lower limit. It will drop down no lower than the supplied limit while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
Refer to shrink_to
for further details.
Sourcepub fn entry(&mut self, key: K) -> Entry<'_, K, V, S>
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S>
Gets the given key’s corresponding entry in the map for in-place manipulation.
Refer to entry
for further details.
§Examples
let mut map = HashMap::new();
let value = map.entry("foo").or_insert(0);
Examples found in repository?
119fn on_add_mine(add: On<Add, Mine>, query: Query<&Mine>, mut index: ResMut<SpatialIndex>) {
120 let mine = query.get(add.entity).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(add.entity);
126}
127
128// Remove despawned mines from our index
129fn on_remove_mine(remove: On<Remove, Mine>, query: Query<&Mine>, mut index: ResMut<SpatialIndex>) {
130 let mine = query.get(remove.entity).unwrap();
131 let tile = (
132 (mine.pos.x / CELL_SIZE).floor() as i32,
133 (mine.pos.y / CELL_SIZE).floor() as i32,
134 );
135 index.map.entry(tile).and_modify(|set| {
136 set.remove(&remove.entity);
137 });
138}
More examples
135 fn prepare_asset(
136 source_asset: Self::SourceAsset,
137 asset_id: AssetId<Self::SourceAsset>,
138 (
139 opaque_draw_functions,
140 material_layout,
141 asset_server,
142 bind_group_allocators,
143 render_material_bindings,
144 gpu_images,
145 image_material_sampler,
146 ): &mut SystemParamItem<Self::Param>,
147 ) -> std::result::Result<Self::ErasedAsset, PrepareAssetError<Self::SourceAsset>> {
148 let material_layout = material_layout.0.clone();
149 let draw_function_id = opaque_draw_functions.read().id::<DrawMaterial>();
150 let bind_group_allocator = bind_group_allocators
151 .get_mut(&TypeId::of::<ImageMaterial>())
152 .unwrap();
153 let Some(image) = gpu_images.get(&source_asset.image) else {
154 return Err(PrepareAssetError::RetryNextUpdate(source_asset));
155 };
156 let unprepared = UnpreparedBindGroup {
157 bindings: BindingResources(vec![
158 (
159 0,
160 OwnedBindingResource::TextureView(
161 TextureViewDimension::D2,
162 image.texture_view.clone(),
163 ),
164 ),
165 (
166 1,
167 OwnedBindingResource::Sampler(
168 SamplerBindingType::NonFiltering,
169 image_material_sampler.0.clone(),
170 ),
171 ),
172 ]),
173 };
174 let binding = match render_material_bindings.entry(asset_id.into()) {
175 Entry::Occupied(mut occupied_entry) => {
176 bind_group_allocator.free(*occupied_entry.get());
177 let new_binding =
178 bind_group_allocator.allocate_unprepared(unprepared, &material_layout);
179 *occupied_entry.get_mut() = new_binding;
180 new_binding
181 }
182 Entry::Vacant(vacant_entry) => *vacant_entry
183 .insert(bind_group_allocator.allocate_unprepared(unprepared, &material_layout)),
184 };
185
186 let mut properties = MaterialProperties {
187 material_layout: Some(material_layout),
188 ..Default::default()
189 };
190 properties.add_draw_function(MaterialDrawFunction, draw_function_id);
191 properties.add_shader(MaterialFragmentShader, asset_server.load(SHADER_ASSET_PATH));
192
193 Ok(PreparedMaterial {
194 binding,
195 properties: Arc::new(properties),
196 })
197 }
Sourcepub fn get<Q>(&self, k: &Q) -> Option<&V>
pub fn get<Q>(&self, k: &Q) -> Option<&V>
Returns a reference to the value corresponding to the key.
Refer to get
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.get("foo"), Some(&0));
Examples found in repository?
More examples
198 fn get_nearby(&self, pos: Vec2) -> Vec<Entity> {
199 let tile = (
200 (pos.x / CELL_SIZE).floor() as i32,
201 (pos.y / CELL_SIZE).floor() as i32,
202 );
203 let mut nearby = Vec::new();
204 for x in -1..2 {
205 for y in -1..2 {
206 if let Some(mines) = self.map.get(&(tile.0 + x, tile.1 + y)) {
207 nearby.extend(mines.iter());
208 }
209 }
210 }
211 nearby
212 }
290fn toggle_tonemapping_method(
291 keys: Res<ButtonInput<KeyCode>>,
292 mut tonemapping: Single<&mut Tonemapping>,
293 mut color_grading: Single<&mut ColorGrading>,
294 per_method_settings: Res<PerMethodSettings>,
295) {
296 if keys.just_pressed(KeyCode::Digit1) {
297 **tonemapping = Tonemapping::None;
298 } else if keys.just_pressed(KeyCode::Digit2) {
299 **tonemapping = Tonemapping::Reinhard;
300 } else if keys.just_pressed(KeyCode::Digit3) {
301 **tonemapping = Tonemapping::ReinhardLuminance;
302 } else if keys.just_pressed(KeyCode::Digit4) {
303 **tonemapping = Tonemapping::AcesFitted;
304 } else if keys.just_pressed(KeyCode::Digit5) {
305 **tonemapping = Tonemapping::AgX;
306 } else if keys.just_pressed(KeyCode::Digit6) {
307 **tonemapping = Tonemapping::SomewhatBoringDisplayTransform;
308 } else if keys.just_pressed(KeyCode::Digit7) {
309 **tonemapping = Tonemapping::TonyMcMapface;
310 } else if keys.just_pressed(KeyCode::Digit8) {
311 **tonemapping = Tonemapping::BlenderFilmic;
312 }
313
314 **color_grading = (*per_method_settings
315 .settings
316 .get::<Tonemapping>(&tonemapping)
317 .as_ref()
318 .unwrap())
319 .clone();
320}
342 fn get_batch_data(
343 (mesh_instances, _render_assets, mesh_allocator): &SystemParamItem<Self::Param>,
344 (_entity, main_entity): (Entity, MainEntity),
345 ) -> Option<(Self::BufferData, Option<Self::CompareData>)> {
346 let RenderMeshInstances::CpuBuilding(ref mesh_instances) = **mesh_instances else {
347 error!(
348 "`get_batch_data` should never be called in GPU mesh uniform \
349 building mode"
350 );
351 return None;
352 };
353 let mesh_instance = mesh_instances.get(&main_entity)?;
354 let first_vertex_index =
355 match mesh_allocator.mesh_vertex_slice(&mesh_instance.mesh_asset_id) {
356 Some(mesh_vertex_slice) => mesh_vertex_slice.range.start,
357 None => 0,
358 };
359 let mesh_uniform = {
360 let mesh_transforms = &mesh_instance.transforms;
361 let (local_from_world_transpose_a, local_from_world_transpose_b) =
362 mesh_transforms.world_from_local.inverse_transpose_3x3();
363 MeshUniform {
364 world_from_local: mesh_transforms.world_from_local.to_transpose(),
365 previous_world_from_local: mesh_transforms.previous_world_from_local.to_transpose(),
366 lightmap_uv_rect: UVec2::ZERO,
367 local_from_world_transpose_a,
368 local_from_world_transpose_b,
369 flags: mesh_transforms.flags,
370 first_vertex_index,
371 current_skin_index: u32::MAX,
372 material_and_lightmap_bind_group_slot: 0,
373 tag: 0,
374 pad: 0,
375 }
376 };
377 Some((mesh_uniform, None))
378 }
379}
380
381impl GetFullBatchData for StencilPipeline {
382 type BufferInputData = MeshInputUniform;
383
384 fn get_index_and_compare_data(
385 (mesh_instances, _, _): &SystemParamItem<Self::Param>,
386 main_entity: MainEntity,
387 ) -> Option<(NonMaxU32, Option<Self::CompareData>)> {
388 // This should only be called during GPU building.
389 let RenderMeshInstances::GpuBuilding(ref mesh_instances) = **mesh_instances else {
390 error!(
391 "`get_index_and_compare_data` should never be called in CPU mesh uniform building \
392 mode"
393 );
394 return None;
395 };
396 let mesh_instance = mesh_instances.get(&main_entity)?;
397 Some((
398 mesh_instance.current_uniform_index,
399 mesh_instance
400 .should_batch()
401 .then_some(mesh_instance.mesh_asset_id),
402 ))
403 }
404
405 fn get_binned_batch_data(
406 (mesh_instances, _render_assets, mesh_allocator): &SystemParamItem<Self::Param>,
407 main_entity: MainEntity,
408 ) -> Option<Self::BufferData> {
409 let RenderMeshInstances::CpuBuilding(ref mesh_instances) = **mesh_instances else {
410 error!(
411 "`get_binned_batch_data` should never be called in GPU mesh uniform building mode"
412 );
413 return None;
414 };
415 let mesh_instance = mesh_instances.get(&main_entity)?;
416 let first_vertex_index =
417 match mesh_allocator.mesh_vertex_slice(&mesh_instance.mesh_asset_id) {
418 Some(mesh_vertex_slice) => mesh_vertex_slice.range.start,
419 None => 0,
420 };
421
422 Some(MeshUniform::new(
423 &mesh_instance.transforms,
424 first_vertex_index,
425 mesh_instance.material_bindings_index.slot,
426 None,
427 None,
428 None,
429 ))
430 }
431
432 fn write_batch_indirect_parameters_metadata(
433 indexed: bool,
434 base_output_index: u32,
435 batch_set_index: Option<NonMaxU32>,
436 indirect_parameters_buffers: &mut UntypedPhaseIndirectParametersBuffers,
437 indirect_parameters_offset: u32,
438 ) {
439 // Note that `IndirectParameters` covers both of these structures, even
440 // though they actually have distinct layouts. See the comment above that
441 // type for more information.
442 let indirect_parameters = IndirectParametersCpuMetadata {
443 base_output_index,
444 batch_set_index: match batch_set_index {
445 None => !0,
446 Some(batch_set_index) => u32::from(batch_set_index),
447 },
448 };
449
450 if indexed {
451 indirect_parameters_buffers
452 .indexed
453 .set(indirect_parameters_offset, indirect_parameters);
454 } else {
455 indirect_parameters_buffers
456 .non_indexed
457 .set(indirect_parameters_offset, indirect_parameters);
458 }
459 }
460
461 fn get_binned_index(
462 _param: &SystemParamItem<Self::Param>,
463 _query_item: MainEntity,
464 ) -> Option<NonMaxU32> {
465 None
466 }
467}
468
469// When defining a phase, we need to extract it from the main world and add it to a resource
470// that will be used by the render world. We need to give that resource all views that will use
471// that phase
472fn extract_camera_phases(
473 mut stencil_phases: ResMut<ViewSortedRenderPhases<Stencil3d>>,
474 cameras: Extract<Query<(Entity, &Camera), With<Camera3d>>>,
475 mut live_entities: Local<HashSet<RetainedViewEntity>>,
476) {
477 live_entities.clear();
478 for (main_entity, camera) in &cameras {
479 if !camera.is_active {
480 continue;
481 }
482 // This is the main camera, so we use the first subview index (0)
483 let retained_view_entity = RetainedViewEntity::new(main_entity.into(), None, 0);
484
485 stencil_phases.insert_or_clear(retained_view_entity);
486 live_entities.insert(retained_view_entity);
487 }
488
489 // Clear out all dead views.
490 stencil_phases.retain(|camera_entity, _| live_entities.contains(camera_entity));
491}
492
493// This is a very important step when writing a custom phase.
494//
495// This system determines which meshes will be added to the phase.
496fn queue_custom_meshes(
497 custom_draw_functions: Res<DrawFunctions<Stencil3d>>,
498 mut pipelines: ResMut<SpecializedMeshPipelines<StencilPipeline>>,
499 pipeline_cache: Res<PipelineCache>,
500 custom_draw_pipeline: Res<StencilPipeline>,
501 render_meshes: Res<RenderAssets<RenderMesh>>,
502 render_mesh_instances: Res<RenderMeshInstances>,
503 mut custom_render_phases: ResMut<ViewSortedRenderPhases<Stencil3d>>,
504 mut views: Query<(&ExtractedView, &RenderVisibleEntities, &Msaa)>,
505 has_marker: Query<(), With<DrawStencil>>,
506) {
507 for (view, visible_entities, msaa) in &mut views {
508 let Some(custom_phase) = custom_render_phases.get_mut(&view.retained_view_entity) else {
509 continue;
510 };
511 let draw_custom = custom_draw_functions.read().id::<DrawMesh3dStencil>();
512
513 // Create the key based on the view.
514 // In this case we only care about MSAA and HDR
515 let view_key = MeshPipelineKey::from_msaa_samples(msaa.samples())
516 | MeshPipelineKey::from_hdr(view.hdr);
517
518 let rangefinder = view.rangefinder3d();
519 // Since our phase can work on any 3d mesh we can reuse the default mesh 3d filter
520 for (render_entity, visible_entity) in visible_entities.iter::<Mesh3d>() {
521 // We only want meshes with the marker component to be queued to our phase.
522 if has_marker.get(*render_entity).is_err() {
523 continue;
524 }
525 let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*visible_entity)
526 else {
527 continue;
528 };
529 let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id) else {
530 continue;
531 };
532
533 // Specialize the key for the current mesh entity
534 // For this example we only specialize based on the mesh topology
535 // but you could have more complex keys and that's where you'd need to create those keys
536 let mut mesh_key = view_key;
537 mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology());
538
539 let pipeline_id = pipelines.specialize(
540 &pipeline_cache,
541 &custom_draw_pipeline,
542 mesh_key,
543 &mesh.layout,
544 );
545 let pipeline_id = match pipeline_id {
546 Ok(id) => id,
547 Err(err) => {
548 error!("{}", err);
549 continue;
550 }
551 };
552 let distance = rangefinder.distance_translation(&mesh_instance.translation);
553 // At this point we have all the data we need to create a phase item and add it to our
554 // phase
555 custom_phase.add(Stencil3d {
556 // Sort the data based on the distance to the view
557 sort_key: FloatOrd(distance),
558 entity: (*render_entity, *visible_entity),
559 pipeline: pipeline_id,
560 draw_function: draw_custom,
561 // Sorted phase items aren't batched
562 batch_range: 0..1,
563 extra_index: PhaseItemExtraIndex::None,
564 indexed: mesh.indexed(),
565 });
566 }
567 }
568}
569
570// Render label used to order our render graph node that will render our phase
571#[derive(RenderLabel, Debug, Clone, Hash, PartialEq, Eq)]
572struct CustomDrawPassLabel;
573
574#[derive(Default)]
575struct CustomDrawNode;
576impl ViewNode for CustomDrawNode {
577 type ViewQuery = (
578 &'static ExtractedCamera,
579 &'static ExtractedView,
580 &'static ViewTarget,
581 Option<&'static MainPassResolutionOverride>,
582 );
583
584 fn run<'w>(
585 &self,
586 graph: &mut RenderGraphContext,
587 render_context: &mut RenderContext<'w>,
588 (camera, view, target, resolution_override): QueryItem<'w, '_, Self::ViewQuery>,
589 world: &'w World,
590 ) -> Result<(), NodeRunError> {
591 // First, we need to get our phases resource
592 let Some(stencil_phases) = world.get_resource::<ViewSortedRenderPhases<Stencil3d>>() else {
593 return Ok(());
594 };
595
596 // Get the view entity from the graph
597 let view_entity = graph.view_entity();
598
599 // Get the phase for the current view running our node
600 let Some(stencil_phase) = stencil_phases.get(&view.retained_view_entity) else {
601 return Ok(());
602 };
603
604 // Render pass setup
605 let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
606 label: Some("stencil pass"),
607 // For the purpose of the example, we will write directly to the view target. A real
608 // stencil pass would write to a custom texture and that texture would be used in later
609 // passes to render custom effects using it.
610 color_attachments: &[Some(target.get_color_attachment())],
611 // We don't bind any depth buffer for this pass
612 depth_stencil_attachment: None,
613 timestamp_writes: None,
614 occlusion_query_set: None,
615 });
616
617 if let Some(viewport) =
618 Viewport::from_viewport_and_override(camera.viewport.as_ref(), resolution_override)
619 {
620 render_pass.set_camera_viewport(&viewport);
621 }
622
623 // Render the phase
624 // This will execute each draw functions of each phase items queued in this phase
625 if let Err(err) = stencil_phase.render(&mut render_pass, world, view_entity) {
626 error!("Error encountered while rendering the stencil phase {err:?}");
627 }
628
629 Ok(())
630 }
416 fn run<'w>(
417 &self,
418 _: &mut RenderGraphContext,
419 render_context: &mut RenderContext<'w>,
420 world: &'w World,
421 ) -> Result<(), NodeRunError> {
422 // Extract the buffers that hold the GPU indirect draw parameters from
423 // the world resources. We're going to read those buffers to determine
424 // how many meshes were actually drawn.
425 let (Some(indirect_parameters_buffers), Some(indirect_parameters_mapping_buffers)) = (
426 world.get_resource::<IndirectParametersBuffers>(),
427 world.get_resource::<IndirectParametersStagingBuffers>(),
428 ) else {
429 return Ok(());
430 };
431
432 // Get the indirect parameters buffers corresponding to the opaque 3D
433 // phase, since all our meshes are in that phase.
434 let Some(phase_indirect_parameters_buffers) =
435 indirect_parameters_buffers.get(&TypeId::of::<Opaque3d>())
436 else {
437 return Ok(());
438 };
439
440 // Grab both the buffers we're copying from and the staging buffers
441 // we're copying to. Remember that we can't map the indirect parameters
442 // buffers directly, so we have to copy their contents to a staging
443 // buffer.
444 let (
445 Some(indexed_data_buffer),
446 Some(indexed_batch_sets_buffer),
447 Some(indirect_parameters_staging_data_buffer),
448 Some(indirect_parameters_staging_batch_sets_buffer),
449 ) = (
450 phase_indirect_parameters_buffers.indexed.data_buffer(),
451 phase_indirect_parameters_buffers
452 .indexed
453 .batch_sets_buffer(),
454 indirect_parameters_mapping_buffers.data.as_ref(),
455 indirect_parameters_mapping_buffers.batch_sets.as_ref(),
456 )
457 else {
458 return Ok(());
459 };
460
461 // Copy from the indirect parameters buffers to the staging buffers.
462 render_context.command_encoder().copy_buffer_to_buffer(
463 indexed_data_buffer,
464 0,
465 indirect_parameters_staging_data_buffer,
466 0,
467 indexed_data_buffer.size(),
468 );
469 render_context.command_encoder().copy_buffer_to_buffer(
470 indexed_batch_sets_buffer,
471 0,
472 indirect_parameters_staging_batch_sets_buffer,
473 0,
474 indexed_batch_sets_buffer.size(),
475 );
476
477 Ok(())
478 }
479}
480
481/// Creates the staging buffers that we use to read back the indirect parameters
482/// from the GPU to the CPU.
483///
484/// We read the indirect parameters from the GPU to the CPU in order to display
485/// the number of meshes that were culled each frame.
486///
487/// We need these staging buffers because `wgpu` doesn't allow us to read the
488/// contents of the indirect parameters buffers directly. We must first copy
489/// them from the GPU to a staging buffer, and then read the staging buffer.
490fn create_indirect_parameters_staging_buffers(
491 mut indirect_parameters_staging_buffers: ResMut<IndirectParametersStagingBuffers>,
492 indirect_parameters_buffers: Res<IndirectParametersBuffers>,
493 render_device: Res<RenderDevice>,
494) {
495 let Some(phase_indirect_parameters_buffers) =
496 indirect_parameters_buffers.get(&TypeId::of::<Opaque3d>())
497 else {
498 return;
499 };
500
501 // Fetch the indirect parameters buffers that we're going to copy from.
502 let (Some(indexed_data_buffer), Some(indexed_batch_set_buffer)) = (
503 phase_indirect_parameters_buffers.indexed.data_buffer(),
504 phase_indirect_parameters_buffers
505 .indexed
506 .batch_sets_buffer(),
507 ) else {
508 return;
509 };
510
511 // Build the staging buffers. Make sure they have the same sizes as the
512 // buffers we're copying from.
513 indirect_parameters_staging_buffers.data =
514 Some(render_device.create_buffer(&BufferDescriptor {
515 label: Some("indexed data staging buffer"),
516 size: indexed_data_buffer.size(),
517 usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST,
518 mapped_at_creation: false,
519 }));
520 indirect_parameters_staging_buffers.batch_sets =
521 Some(render_device.create_buffer(&BufferDescriptor {
522 label: Some("indexed batch set staging buffer"),
523 size: indexed_batch_set_buffer.size(),
524 usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST,
525 mapped_at_creation: false,
526 }));
527}
377pub fn queue_colored_mesh2d(
378 transparent_draw_functions: Res<DrawFunctions<Transparent2d>>,
379 colored_mesh2d_pipeline: Res<ColoredMesh2dPipeline>,
380 mut pipelines: ResMut<SpecializedRenderPipelines<ColoredMesh2dPipeline>>,
381 pipeline_cache: Res<PipelineCache>,
382 render_meshes: Res<RenderAssets<RenderMesh>>,
383 render_mesh_instances: Res<RenderColoredMesh2dInstances>,
384 mut transparent_render_phases: ResMut<ViewSortedRenderPhases<Transparent2d>>,
385 views: Query<(&RenderVisibleEntities, &ExtractedView, &Msaa)>,
386) {
387 if render_mesh_instances.is_empty() {
388 return;
389 }
390 // Iterate each view (a camera is a view)
391 for (visible_entities, view, msaa) in &views {
392 let Some(transparent_phase) = transparent_render_phases.get_mut(&view.retained_view_entity)
393 else {
394 continue;
395 };
396
397 let draw_colored_mesh2d = transparent_draw_functions.read().id::<DrawColoredMesh2d>();
398
399 let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples())
400 | Mesh2dPipelineKey::from_hdr(view.hdr);
401
402 // Queue all entities visible to that view
403 for (render_entity, visible_entity) in visible_entities.iter::<Mesh2d>() {
404 if let Some(mesh_instance) = render_mesh_instances.get(visible_entity) {
405 let mesh2d_handle = mesh_instance.mesh_asset_id;
406 let mesh2d_transforms = &mesh_instance.transforms;
407 // Get our specialized pipeline
408 let mut mesh2d_key = mesh_key;
409 let Some(mesh) = render_meshes.get(mesh2d_handle) else {
410 continue;
411 };
412 mesh2d_key |= Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology());
413
414 let pipeline_id =
415 pipelines.specialize(&pipeline_cache, &colored_mesh2d_pipeline, mesh2d_key);
416
417 let mesh_z = mesh2d_transforms.world_from_local.translation.z;
418 transparent_phase.add(Transparent2d {
419 entity: (*render_entity, *visible_entity),
420 draw_function: draw_colored_mesh2d,
421 pipeline: pipeline_id,
422 // The 2d render items are sorted according to their z value before rendering,
423 // in order to get correct transparency
424 sort_key: FloatOrd(mesh_z),
425 // This material is not batched
426 batch_range: 0..1,
427 extra_index: PhaseItemExtraIndex::None,
428 extracted_index: usize::MAX,
429 indexed: mesh.indexed(),
430 });
431 }
432 }
433 }
434}
Sourcepub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
Returns the key-value pair corresponding to the supplied key.
Refer to get_key_value
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.get_key_value("foo"), Some((&"foo", &0)));
Sourcepub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
pub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
Refer to get_key_value_mut
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.get_key_value_mut("foo"), Some((&"foo", &mut 0)));
Sourcepub fn contains_key<Q>(&self, k: &Q) -> bool
pub fn contains_key<Q>(&self, k: &Q) -> bool
Returns true
if the map contains a value for the specified key.
Refer to contains_key
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert!(map.contains_key("foo"));
Sourcepub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
Returns a mutable reference to the value corresponding to the key.
Refer to get_mut
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.get_mut("foo"), Some(&mut 0));
Examples found in repository?
337fn update_color_grading_settings(
338 keys: Res<ButtonInput<KeyCode>>,
339 time: Res<Time>,
340 mut per_method_settings: ResMut<PerMethodSettings>,
341 tonemapping: Single<&Tonemapping>,
342 current_scene: Res<CurrentScene>,
343 mut selected_parameter: ResMut<SelectedParameter>,
344) {
345 let color_grading = per_method_settings.settings.get_mut(*tonemapping).unwrap();
346 let mut dt = time.delta_secs() * 0.25;
347 if keys.pressed(KeyCode::ArrowLeft) {
348 dt = -dt;
349 }
350
351 if keys.just_pressed(KeyCode::ArrowDown) {
352 selected_parameter.next();
353 }
354 if keys.just_pressed(KeyCode::ArrowUp) {
355 selected_parameter.prev();
356 }
357 if keys.pressed(KeyCode::ArrowLeft) || keys.pressed(KeyCode::ArrowRight) {
358 match selected_parameter.value {
359 0 => {
360 color_grading.global.exposure += dt;
361 }
362 1 => {
363 color_grading
364 .all_sections_mut()
365 .for_each(|section| section.gamma += dt);
366 }
367 2 => {
368 color_grading
369 .all_sections_mut()
370 .for_each(|section| section.saturation += dt);
371 }
372 3 => {
373 color_grading.global.post_saturation += dt;
374 }
375 _ => {}
376 }
377 }
378
379 if keys.just_pressed(KeyCode::Space) {
380 for (_, grading) in per_method_settings.settings.iter_mut() {
381 *grading = ColorGrading::default();
382 }
383 }
384
385 if keys.just_pressed(KeyCode::Enter) && current_scene.0 == 1 {
386 for (mapper, grading) in per_method_settings.settings.iter_mut() {
387 *grading = PerMethodSettings::basic_scene_recommendation(*mapper);
388 }
389 }
390}
More examples
124fn queue_custom(
125 transparent_3d_draw_functions: Res<DrawFunctions<Transparent3d>>,
126 custom_pipeline: Res<CustomPipeline>,
127 mut pipelines: ResMut<SpecializedMeshPipelines<CustomPipeline>>,
128 pipeline_cache: Res<PipelineCache>,
129 meshes: Res<RenderAssets<RenderMesh>>,
130 render_mesh_instances: Res<RenderMeshInstances>,
131 material_meshes: Query<(Entity, &MainEntity), With<InstanceMaterialData>>,
132 mut transparent_render_phases: ResMut<ViewSortedRenderPhases<Transparent3d>>,
133 views: Query<(&ExtractedView, &Msaa)>,
134) {
135 let draw_custom = transparent_3d_draw_functions.read().id::<DrawCustom>();
136
137 for (view, msaa) in &views {
138 let Some(transparent_phase) = transparent_render_phases.get_mut(&view.retained_view_entity)
139 else {
140 continue;
141 };
142
143 let msaa_key = MeshPipelineKey::from_msaa_samples(msaa.samples());
144
145 let view_key = msaa_key | MeshPipelineKey::from_hdr(view.hdr);
146 let rangefinder = view.rangefinder3d();
147 for (entity, main_entity) in &material_meshes {
148 let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*main_entity)
149 else {
150 continue;
151 };
152 let Some(mesh) = meshes.get(mesh_instance.mesh_asset_id) else {
153 continue;
154 };
155 let key =
156 view_key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology());
157 let pipeline = pipelines
158 .specialize(&pipeline_cache, &custom_pipeline, key, &mesh.layout)
159 .unwrap();
160 transparent_phase.add(Transparent3d {
161 entity: (entity, *main_entity),
162 pipeline,
163 draw_function: draw_custom,
164 distance: rangefinder.distance_translation(&mesh_instance.translation),
165 batch_range: 0..1,
166 extra_index: PhaseItemExtraIndex::None,
167 indexed: true,
168 });
169 }
170 }
171}
135 fn prepare_asset(
136 source_asset: Self::SourceAsset,
137 asset_id: AssetId<Self::SourceAsset>,
138 (
139 opaque_draw_functions,
140 material_layout,
141 asset_server,
142 bind_group_allocators,
143 render_material_bindings,
144 gpu_images,
145 image_material_sampler,
146 ): &mut SystemParamItem<Self::Param>,
147 ) -> std::result::Result<Self::ErasedAsset, PrepareAssetError<Self::SourceAsset>> {
148 let material_layout = material_layout.0.clone();
149 let draw_function_id = opaque_draw_functions.read().id::<DrawMaterial>();
150 let bind_group_allocator = bind_group_allocators
151 .get_mut(&TypeId::of::<ImageMaterial>())
152 .unwrap();
153 let Some(image) = gpu_images.get(&source_asset.image) else {
154 return Err(PrepareAssetError::RetryNextUpdate(source_asset));
155 };
156 let unprepared = UnpreparedBindGroup {
157 bindings: BindingResources(vec![
158 (
159 0,
160 OwnedBindingResource::TextureView(
161 TextureViewDimension::D2,
162 image.texture_view.clone(),
163 ),
164 ),
165 (
166 1,
167 OwnedBindingResource::Sampler(
168 SamplerBindingType::NonFiltering,
169 image_material_sampler.0.clone(),
170 ),
171 ),
172 ]),
173 };
174 let binding = match render_material_bindings.entry(asset_id.into()) {
175 Entry::Occupied(mut occupied_entry) => {
176 bind_group_allocator.free(*occupied_entry.get());
177 let new_binding =
178 bind_group_allocator.allocate_unprepared(unprepared, &material_layout);
179 *occupied_entry.get_mut() = new_binding;
180 new_binding
181 }
182 Entry::Vacant(vacant_entry) => *vacant_entry
183 .insert(bind_group_allocator.allocate_unprepared(unprepared, &material_layout)),
184 };
185
186 let mut properties = MaterialProperties {
187 material_layout: Some(material_layout),
188 ..Default::default()
189 };
190 properties.add_draw_function(MaterialDrawFunction, draw_function_id);
191 properties.add_shader(MaterialFragmentShader, asset_server.load(SHADER_ASSET_PATH));
192
193 Ok(PreparedMaterial {
194 binding,
195 properties: Arc::new(properties),
196 })
197 }
198}
199
200/// set up a simple 3D scene
201fn setup(
202 mut commands: Commands,
203 mut meshes: ResMut<Assets<Mesh>>,
204 mut materials: ResMut<Assets<ImageMaterial>>,
205 asset_server: Res<AssetServer>,
206) {
207 // cube
208 commands.spawn((
209 Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
210 ImageMaterial3d(materials.add(ImageMaterial {
211 image: asset_server.load("branding/icon.png"),
212 })),
213 Transform::from_xyz(0.0, 0.5, 0.0),
214 ));
215 // light
216 commands.spawn((
217 PointLight {
218 shadows_enabled: true,
219 ..default()
220 },
221 Transform::from_xyz(4.0, 8.0, 4.0),
222 ));
223 // camera
224 commands.spawn((
225 Camera3d::default(),
226 Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
227 ));
228}
229
230fn extract_image_materials(
231 mut material_instances: ResMut<RenderMaterialInstances>,
232 changed_meshes_query: Extract<
233 Query<
234 (Entity, &ViewVisibility, &ImageMaterial3d),
235 Or<(Changed<ViewVisibility>, Changed<ImageMaterial3d>)>,
236 >,
237 >,
238) {
239 let last_change_tick = material_instances.current_change_tick;
240
241 for (entity, view_visibility, material) in &changed_meshes_query {
242 if view_visibility.get() {
243 material_instances.instances.insert(
244 entity.into(),
245 RenderMaterialInstance {
246 asset_id: material.0.id().untyped(),
247 last_change_tick,
248 },
249 );
250 } else {
251 material_instances
252 .instances
253 .remove(&MainEntity::from(entity));
254 }
255 }
256}
257
258fn check_entities_needing_specialization(
259 needs_specialization: Query<
260 Entity,
261 (
262 Or<(
263 Changed<Mesh3d>,
264 AssetChanged<Mesh3d>,
265 Changed<ImageMaterial3d>,
266 AssetChanged<ImageMaterial3d>,
267 )>,
268 With<ImageMaterial3d>,
269 ),
270 >,
271 mut par_local: Local<Parallel<Vec<Entity>>>,
272 mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<ImageMaterial>>,
273) {
274 entities_needing_specialization.clear();
275
276 needs_specialization
277 .par_iter()
278 .for_each(|entity| par_local.borrow_local_mut().push(entity));
279
280 par_local.drain_into(&mut entities_needing_specialization);
281}
282
283fn extract_image_materials_needing_specialization(
284 entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<ImageMaterial>>>,
285 mut entity_specialization_ticks: ResMut<EntitySpecializationTicks>,
286 mut removed_mesh_material_components: Extract<RemovedComponents<ImageMaterial3d>>,
287 mut specialized_material_pipeline_cache: ResMut<SpecializedMaterialPipelineCache>,
288 views: Query<&ExtractedView>,
289 ticks: SystemChangeTick,
290) {
291 // Clean up any despawned entities, we do this first in case the removed material was re-added
292 // the same frame, thus will appear both in the removed components list and have been added to
293 // the `EntitiesNeedingSpecialization` collection by triggering the `Changed` filter
294 for entity in removed_mesh_material_components.read() {
295 entity_specialization_ticks.remove(&MainEntity::from(entity));
296 for view in views {
297 if let Some(cache) =
298 specialized_material_pipeline_cache.get_mut(&view.retained_view_entity)
299 {
300 cache.remove(&MainEntity::from(entity));
301 }
302 }
303 }
304
305 for entity in entities_needing_specialization.iter() {
306 // Update the entity's specialization tick with this run's tick
307 entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
308 }
309}
377pub fn queue_colored_mesh2d(
378 transparent_draw_functions: Res<DrawFunctions<Transparent2d>>,
379 colored_mesh2d_pipeline: Res<ColoredMesh2dPipeline>,
380 mut pipelines: ResMut<SpecializedRenderPipelines<ColoredMesh2dPipeline>>,
381 pipeline_cache: Res<PipelineCache>,
382 render_meshes: Res<RenderAssets<RenderMesh>>,
383 render_mesh_instances: Res<RenderColoredMesh2dInstances>,
384 mut transparent_render_phases: ResMut<ViewSortedRenderPhases<Transparent2d>>,
385 views: Query<(&RenderVisibleEntities, &ExtractedView, &Msaa)>,
386) {
387 if render_mesh_instances.is_empty() {
388 return;
389 }
390 // Iterate each view (a camera is a view)
391 for (visible_entities, view, msaa) in &views {
392 let Some(transparent_phase) = transparent_render_phases.get_mut(&view.retained_view_entity)
393 else {
394 continue;
395 };
396
397 let draw_colored_mesh2d = transparent_draw_functions.read().id::<DrawColoredMesh2d>();
398
399 let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples())
400 | Mesh2dPipelineKey::from_hdr(view.hdr);
401
402 // Queue all entities visible to that view
403 for (render_entity, visible_entity) in visible_entities.iter::<Mesh2d>() {
404 if let Some(mesh_instance) = render_mesh_instances.get(visible_entity) {
405 let mesh2d_handle = mesh_instance.mesh_asset_id;
406 let mesh2d_transforms = &mesh_instance.transforms;
407 // Get our specialized pipeline
408 let mut mesh2d_key = mesh_key;
409 let Some(mesh) = render_meshes.get(mesh2d_handle) else {
410 continue;
411 };
412 mesh2d_key |= Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology());
413
414 let pipeline_id =
415 pipelines.specialize(&pipeline_cache, &colored_mesh2d_pipeline, mesh2d_key);
416
417 let mesh_z = mesh2d_transforms.world_from_local.translation.z;
418 transparent_phase.add(Transparent2d {
419 entity: (*render_entity, *visible_entity),
420 draw_function: draw_colored_mesh2d,
421 pipeline: pipeline_id,
422 // The 2d render items are sorted according to their z value before rendering,
423 // in order to get correct transparency
424 sort_key: FloatOrd(mesh_z),
425 // This material is not batched
426 batch_range: 0..1,
427 extra_index: PhaseItemExtraIndex::None,
428 extracted_index: usize::MAX,
429 indexed: mesh.indexed(),
430 });
431 }
432 }
433 }
434}
215fn queue_custom_phase_item(
216 pipeline_cache: Res<PipelineCache>,
217 mut pipeline: ResMut<CustomPhasePipeline>,
218 mut opaque_render_phases: ResMut<ViewBinnedRenderPhases<Opaque3d>>,
219 opaque_draw_functions: Res<DrawFunctions<Opaque3d>>,
220 views: Query<(&ExtractedView, &RenderVisibleEntities, &Msaa)>,
221 mut next_tick: Local<Tick>,
222) {
223 let draw_custom_phase_item = opaque_draw_functions
224 .read()
225 .id::<DrawCustomPhaseItemCommands>();
226
227 // Render phases are per-view, so we need to iterate over all views so that
228 // the entity appears in them. (In this example, we have only one view, but
229 // it's good practice to loop over all views anyway.)
230 for (view, view_visible_entities, msaa) in views.iter() {
231 let Some(opaque_phase) = opaque_render_phases.get_mut(&view.retained_view_entity) else {
232 continue;
233 };
234
235 // Find all the custom rendered entities that are visible from this
236 // view.
237 for &entity in view_visible_entities.get::<CustomRenderedEntity>().iter() {
238 // Ordinarily, the [`SpecializedRenderPipeline::Key`] would contain
239 // some per-view settings, such as whether the view is HDR, but for
240 // simplicity's sake we simply hard-code the view's characteristics,
241 // with the exception of number of MSAA samples.
242 let Ok(pipeline_id) = pipeline
243 .variants
244 .specialize(&pipeline_cache, CustomPhaseKey(*msaa))
245 else {
246 continue;
247 };
248
249 // Bump the change tick in order to force Bevy to rebuild the bin.
250 let this_tick = next_tick.get() + 1;
251 next_tick.set(this_tick);
252
253 // Add the custom render item. We use the
254 // [`BinnedRenderPhaseType::NonMesh`] type to skip the special
255 // handling that Bevy has for meshes (preprocessing, indirect
256 // draws, etc.)
257 //
258 // The asset ID is arbitrary; we simply use [`AssetId::invalid`],
259 // but you can use anything you like. Note that the asset ID need
260 // not be the ID of a [`Mesh`].
261 opaque_phase.add(
262 Opaque3dBatchSetKey {
263 draw_function: draw_custom_phase_item,
264 pipeline: pipeline_id,
265 material_bind_group_index: None,
266 lightmap_slab: None,
267 vertex_slab: default(),
268 index_slab: None,
269 },
270 Opaque3dBinKey {
271 asset_id: AssetId::<Mesh>::invalid().untyped(),
272 },
273 entity,
274 InputUniformIndex::default(),
275 BinnedRenderPhaseType::NonMesh,
276 *next_tick,
277 );
278 }
279 }
280}
496fn queue_custom_meshes(
497 custom_draw_functions: Res<DrawFunctions<Stencil3d>>,
498 mut pipelines: ResMut<SpecializedMeshPipelines<StencilPipeline>>,
499 pipeline_cache: Res<PipelineCache>,
500 custom_draw_pipeline: Res<StencilPipeline>,
501 render_meshes: Res<RenderAssets<RenderMesh>>,
502 render_mesh_instances: Res<RenderMeshInstances>,
503 mut custom_render_phases: ResMut<ViewSortedRenderPhases<Stencil3d>>,
504 mut views: Query<(&ExtractedView, &RenderVisibleEntities, &Msaa)>,
505 has_marker: Query<(), With<DrawStencil>>,
506) {
507 for (view, visible_entities, msaa) in &mut views {
508 let Some(custom_phase) = custom_render_phases.get_mut(&view.retained_view_entity) else {
509 continue;
510 };
511 let draw_custom = custom_draw_functions.read().id::<DrawMesh3dStencil>();
512
513 // Create the key based on the view.
514 // In this case we only care about MSAA and HDR
515 let view_key = MeshPipelineKey::from_msaa_samples(msaa.samples())
516 | MeshPipelineKey::from_hdr(view.hdr);
517
518 let rangefinder = view.rangefinder3d();
519 // Since our phase can work on any 3d mesh we can reuse the default mesh 3d filter
520 for (render_entity, visible_entity) in visible_entities.iter::<Mesh3d>() {
521 // We only want meshes with the marker component to be queued to our phase.
522 if has_marker.get(*render_entity).is_err() {
523 continue;
524 }
525 let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*visible_entity)
526 else {
527 continue;
528 };
529 let Some(mesh) = render_meshes.get(mesh_instance.mesh_asset_id) else {
530 continue;
531 };
532
533 // Specialize the key for the current mesh entity
534 // For this example we only specialize based on the mesh topology
535 // but you could have more complex keys and that's where you'd need to create those keys
536 let mut mesh_key = view_key;
537 mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology());
538
539 let pipeline_id = pipelines.specialize(
540 &pipeline_cache,
541 &custom_draw_pipeline,
542 mesh_key,
543 &mesh.layout,
544 );
545 let pipeline_id = match pipeline_id {
546 Ok(id) => id,
547 Err(err) => {
548 error!("{}", err);
549 continue;
550 }
551 };
552 let distance = rangefinder.distance_translation(&mesh_instance.translation);
553 // At this point we have all the data we need to create a phase item and add it to our
554 // phase
555 custom_phase.add(Stencil3d {
556 // Sort the data based on the distance to the view
557 sort_key: FloatOrd(distance),
558 entity: (*render_entity, *visible_entity),
559 pipeline: pipeline_id,
560 draw_function: draw_custom,
561 // Sorted phase items aren't batched
562 batch_range: 0..1,
563 extra_index: PhaseItemExtraIndex::None,
564 indexed: mesh.indexed(),
565 });
566 }
567 }
568}
Sourcepub fn get_many_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<&mut V>; N]
pub fn get_many_mut<Q, const N: usize>( &mut self, ks: [&Q; N], ) -> [Option<&mut V>; N]
Attempts to get mutable references to N
values in the map at once.
Refer to get_many_mut
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
let result = map.get_many_mut(["foo", "bar"]);
assert_eq!(result, [Some(&mut 0), Some(&mut 1)]);
Sourcepub fn get_many_key_value_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<(&K, &mut V)>; N]
pub fn get_many_key_value_mut<Q, const N: usize>( &mut self, ks: [&Q; N], ) -> [Option<(&K, &mut V)>; N]
Attempts to get mutable references to N
values in the map at once, with immutable
references to the corresponding keys.
Refer to get_many_key_value_mut
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
map.insert("bar", 1);
map.insert("baz", 2);
let result = map.get_many_key_value_mut(["foo", "bar"]);
assert_eq!(result, [Some((&"foo", &mut 0)), Some((&"bar", &mut 1))]);
Sourcepub fn insert(&mut self, k: K, v: V) -> Option<V>
pub fn insert(&mut self, k: K, v: V) -> Option<V>
Inserts a key-value pair into the map.
Refer to insert
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.get("foo"), Some(&0));
Examples found in repository?
More examples
578 fn default() -> Self {
579 let mut settings = <HashMap<_, _>>::default();
580
581 for method in [
582 Tonemapping::None,
583 Tonemapping::Reinhard,
584 Tonemapping::ReinhardLuminance,
585 Tonemapping::AcesFitted,
586 Tonemapping::AgX,
587 Tonemapping::SomewhatBoringDisplayTransform,
588 Tonemapping::TonyMcMapface,
589 Tonemapping::BlenderFilmic,
590 ] {
591 settings.insert(
592 method,
593 PerMethodSettings::basic_scene_recommendation(method),
594 );
595 }
596
597 Self { settings }
598 }
75fn init_image_material_resources(
76 mut commands: Commands,
77 render_device: Res<RenderDevice>,
78 mut bind_group_allocators: ResMut<MaterialBindGroupAllocators>,
79) {
80 let bind_group_layout = render_device.create_bind_group_layout(
81 "image_material_layout",
82 &BindGroupLayoutEntries::sequential(
83 ShaderStages::FRAGMENT,
84 (
85 texture_2d(TextureSampleType::Float { filterable: false }),
86 sampler(SamplerBindingType::NonFiltering),
87 ),
88 ),
89 );
90 let sampler = render_device.create_sampler(&SamplerDescriptor::default());
91 commands.insert_resource(ImageMaterialBindGroupLayout(bind_group_layout.clone()));
92 commands.insert_resource(ImageMaterialBindGroupSampler(sampler));
93
94 bind_group_allocators.insert(
95 TypeId::of::<ImageMaterial>(),
96 MaterialBindGroupAllocator::new(&render_device, None, None, bind_group_layout, None),
97 );
98}
99
100#[derive(Resource)]
101struct ImageMaterialBindGroupLayout(BindGroupLayout);
102
103#[derive(Resource)]
104struct ImageMaterialBindGroupSampler(Sampler);
105
106#[derive(Component)]
107struct ImageMaterial3d(Handle<ImageMaterial>);
108
109impl AsAssetId for ImageMaterial3d {
110 type Asset = ImageMaterial;
111
112 fn as_asset_id(&self) -> AssetId<Self::Asset> {
113 self.0.id()
114 }
115}
116
117#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
118struct ImageMaterial {
119 image: Handle<Image>,
120}
121
122impl ErasedRenderAsset for ImageMaterial {
123 type SourceAsset = ImageMaterial;
124 type ErasedAsset = PreparedMaterial;
125 type Param = (
126 SRes<DrawFunctions<Opaque3d>>,
127 SRes<ImageMaterialBindGroupLayout>,
128 SRes<AssetServer>,
129 SResMut<MaterialBindGroupAllocators>,
130 SResMut<RenderMaterialBindings>,
131 SRes<RenderAssets<GpuImage>>,
132 SRes<ImageMaterialBindGroupSampler>,
133 );
134
135 fn prepare_asset(
136 source_asset: Self::SourceAsset,
137 asset_id: AssetId<Self::SourceAsset>,
138 (
139 opaque_draw_functions,
140 material_layout,
141 asset_server,
142 bind_group_allocators,
143 render_material_bindings,
144 gpu_images,
145 image_material_sampler,
146 ): &mut SystemParamItem<Self::Param>,
147 ) -> std::result::Result<Self::ErasedAsset, PrepareAssetError<Self::SourceAsset>> {
148 let material_layout = material_layout.0.clone();
149 let draw_function_id = opaque_draw_functions.read().id::<DrawMaterial>();
150 let bind_group_allocator = bind_group_allocators
151 .get_mut(&TypeId::of::<ImageMaterial>())
152 .unwrap();
153 let Some(image) = gpu_images.get(&source_asset.image) else {
154 return Err(PrepareAssetError::RetryNextUpdate(source_asset));
155 };
156 let unprepared = UnpreparedBindGroup {
157 bindings: BindingResources(vec![
158 (
159 0,
160 OwnedBindingResource::TextureView(
161 TextureViewDimension::D2,
162 image.texture_view.clone(),
163 ),
164 ),
165 (
166 1,
167 OwnedBindingResource::Sampler(
168 SamplerBindingType::NonFiltering,
169 image_material_sampler.0.clone(),
170 ),
171 ),
172 ]),
173 };
174 let binding = match render_material_bindings.entry(asset_id.into()) {
175 Entry::Occupied(mut occupied_entry) => {
176 bind_group_allocator.free(*occupied_entry.get());
177 let new_binding =
178 bind_group_allocator.allocate_unprepared(unprepared, &material_layout);
179 *occupied_entry.get_mut() = new_binding;
180 new_binding
181 }
182 Entry::Vacant(vacant_entry) => *vacant_entry
183 .insert(bind_group_allocator.allocate_unprepared(unprepared, &material_layout)),
184 };
185
186 let mut properties = MaterialProperties {
187 material_layout: Some(material_layout),
188 ..Default::default()
189 };
190 properties.add_draw_function(MaterialDrawFunction, draw_function_id);
191 properties.add_shader(MaterialFragmentShader, asset_server.load(SHADER_ASSET_PATH));
192
193 Ok(PreparedMaterial {
194 binding,
195 properties: Arc::new(properties),
196 })
197 }
198}
199
200/// set up a simple 3D scene
201fn setup(
202 mut commands: Commands,
203 mut meshes: ResMut<Assets<Mesh>>,
204 mut materials: ResMut<Assets<ImageMaterial>>,
205 asset_server: Res<AssetServer>,
206) {
207 // cube
208 commands.spawn((
209 Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))),
210 ImageMaterial3d(materials.add(ImageMaterial {
211 image: asset_server.load("branding/icon.png"),
212 })),
213 Transform::from_xyz(0.0, 0.5, 0.0),
214 ));
215 // light
216 commands.spawn((
217 PointLight {
218 shadows_enabled: true,
219 ..default()
220 },
221 Transform::from_xyz(4.0, 8.0, 4.0),
222 ));
223 // camera
224 commands.spawn((
225 Camera3d::default(),
226 Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
227 ));
228}
229
230fn extract_image_materials(
231 mut material_instances: ResMut<RenderMaterialInstances>,
232 changed_meshes_query: Extract<
233 Query<
234 (Entity, &ViewVisibility, &ImageMaterial3d),
235 Or<(Changed<ViewVisibility>, Changed<ImageMaterial3d>)>,
236 >,
237 >,
238) {
239 let last_change_tick = material_instances.current_change_tick;
240
241 for (entity, view_visibility, material) in &changed_meshes_query {
242 if view_visibility.get() {
243 material_instances.instances.insert(
244 entity.into(),
245 RenderMaterialInstance {
246 asset_id: material.0.id().untyped(),
247 last_change_tick,
248 },
249 );
250 } else {
251 material_instances
252 .instances
253 .remove(&MainEntity::from(entity));
254 }
255 }
256}
257
258fn check_entities_needing_specialization(
259 needs_specialization: Query<
260 Entity,
261 (
262 Or<(
263 Changed<Mesh3d>,
264 AssetChanged<Mesh3d>,
265 Changed<ImageMaterial3d>,
266 AssetChanged<ImageMaterial3d>,
267 )>,
268 With<ImageMaterial3d>,
269 ),
270 >,
271 mut par_local: Local<Parallel<Vec<Entity>>>,
272 mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<ImageMaterial>>,
273) {
274 entities_needing_specialization.clear();
275
276 needs_specialization
277 .par_iter()
278 .for_each(|entity| par_local.borrow_local_mut().push(entity));
279
280 par_local.drain_into(&mut entities_needing_specialization);
281}
282
283fn extract_image_materials_needing_specialization(
284 entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<ImageMaterial>>>,
285 mut entity_specialization_ticks: ResMut<EntitySpecializationTicks>,
286 mut removed_mesh_material_components: Extract<RemovedComponents<ImageMaterial3d>>,
287 mut specialized_material_pipeline_cache: ResMut<SpecializedMaterialPipelineCache>,
288 views: Query<&ExtractedView>,
289 ticks: SystemChangeTick,
290) {
291 // Clean up any despawned entities, we do this first in case the removed material was re-added
292 // the same frame, thus will appear both in the removed components list and have been added to
293 // the `EntitiesNeedingSpecialization` collection by triggering the `Changed` filter
294 for entity in removed_mesh_material_components.read() {
295 entity_specialization_ticks.remove(&MainEntity::from(entity));
296 for view in views {
297 if let Some(cache) =
298 specialized_material_pipeline_cache.get_mut(&view.retained_view_entity)
299 {
300 cache.remove(&MainEntity::from(entity));
301 }
302 }
303 }
304
305 for entity in entities_needing_specialization.iter() {
306 // Update the entity's specialization tick with this run's tick
307 entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
308 }
309}
330pub fn extract_colored_mesh2d(
331 mut commands: Commands,
332 mut previous_len: Local<usize>,
333 // When extracting, you must use `Extract` to mark the `SystemParam`s
334 // which should be taken from the main world.
335 query: Extract<
336 Query<
337 (
338 Entity,
339 RenderEntity,
340 &ViewVisibility,
341 &GlobalTransform,
342 &Mesh2d,
343 ),
344 With<ColoredMesh2d>,
345 >,
346 >,
347 mut render_mesh_instances: ResMut<RenderColoredMesh2dInstances>,
348) {
349 let mut values = Vec::with_capacity(*previous_len);
350 for (entity, render_entity, view_visibility, transform, handle) in &query {
351 if !view_visibility.get() {
352 continue;
353 }
354
355 let transforms = Mesh2dTransforms {
356 world_from_local: (&transform.affine()).into(),
357 flags: MeshFlags::empty().bits(),
358 };
359
360 values.push((render_entity, ColoredMesh2d));
361 render_mesh_instances.insert(
362 entity.into(),
363 RenderMesh2dInstance {
364 mesh_asset_id: handle.0.id(),
365 transforms,
366 material_bind_group_id: Material2dBindGroupId::default(),
367 automatic_batching: false,
368 tag: 0,
369 },
370 );
371 }
372 *previous_len = values.len();
373 commands.try_insert_batch(values);
374}
67fn setup() {
68 let mut z = <HashMap<_, _>>::default();
69 z.insert("Hello".to_string(), 1.0);
70 let value: Box<dyn Reflect> = Box::new(A {
71 x: 1,
72 y: vec![1, 2],
73 z,
74 });
75
76 // There are a number of different "reflect traits", which each expose different operations on
77 // the underlying type
78 match value.reflect_ref() {
79 // `Struct` is a trait automatically implemented for structs that derive Reflect. This trait
80 // allows you to interact with fields via their string names or indices
81 ReflectRef::Struct(value) => {
82 info!(
83 "This is a 'struct' type with an 'x' value of {}",
84 value.get_field::<usize>("x").unwrap()
85 );
86 }
87 // `TupleStruct` is a trait automatically implemented for tuple structs that derive Reflect.
88 // This trait allows you to interact with fields via their indices
89 ReflectRef::TupleStruct(_) => {}
90 // `Tuple` is a special trait that can be manually implemented (instead of deriving
91 // Reflect). This exposes "tuple" operations on your type, allowing you to interact
92 // with fields via their indices. Tuple is automatically implemented for tuples of
93 // arity 12 or less.
94 ReflectRef::Tuple(_) => {}
95 // `Enum` is a trait automatically implemented for enums that derive Reflect. This trait allows you
96 // to interact with the current variant and its fields (if it has any)
97 ReflectRef::Enum(_) => {}
98 // `List` is a special trait that can be manually implemented (instead of deriving Reflect).
99 // This exposes "list" operations on your type, such as insertion. `List` is automatically
100 // implemented for relevant core types like Vec<T>.
101 ReflectRef::List(_) => {}
102 // `Array` is a special trait that can be manually implemented (instead of deriving Reflect).
103 // This exposes "array" operations on your type, such as indexing. `Array`
104 // is automatically implemented for relevant core types like [T; N].
105 ReflectRef::Array(_) => {}
106 // `Map` is a special trait that can be manually implemented (instead of deriving Reflect).
107 // This exposes "map" operations on your type, such as getting / inserting by key.
108 // Map is automatically implemented for relevant core types like HashMap<K, V>
109 ReflectRef::Map(_) => {}
110 // `Set` is a special trait that can be manually implemented (instead of deriving Reflect).
111 // This exposes "set" operations on your type, such as getting / inserting by value.
112 // Set is automatically implemented for relevant core types like HashSet<T>
113 ReflectRef::Set(_) => {}
114 // `Function` is a special trait that can be manually implemented (instead of deriving Reflect).
115 // This exposes "function" operations on your type, such as calling it with arguments.
116 // This trait is automatically implemented for types like DynamicFunction.
117 // This variant only exists if the `reflect_functions` feature is enabled.
118 #[cfg(feature = "reflect_functions")]
119 ReflectRef::Function(_) => {}
120 // `Opaque` types do not implement any of the other traits above. They are simply a Reflect
121 // implementation. Opaque is implemented for opaque types like String and Instant,
122 // but also include primitive types like i32, usize, and f32 (despite not technically being opaque).
123 ReflectRef::Opaque(_) => {}
124 #[expect(
125 clippy::allow_attributes,
126 reason = "`unreachable_patterns` is not always linted"
127 )]
128 #[allow(
129 unreachable_patterns,
130 reason = "This example cannot always detect when `bevy_reflect/functions` is enabled."
131 )]
132 _ => {}
133 }
134
135 let mut dynamic_list = DynamicList::default();
136 dynamic_list.push(3u32);
137 dynamic_list.push(4u32);
138 dynamic_list.push(5u32);
139
140 let mut value: A = value.take::<A>().unwrap();
141 value.y.apply(&dynamic_list);
142 assert_eq!(value.y, vec![3u32, 4u32, 5u32]);
143
144 // reference types defined above that are only used to demonstrate reflect
145 // derive functionality:
146 _ = || -> (A, B, C, D, E, F) { unreachable!() };
147}
Sourcepub fn try_insert(
&mut self,
key: K,
value: V,
) -> Result<&mut V, OccupiedError<'_, K, V, S>>
pub fn try_insert( &mut self, key: K, value: V, ) -> Result<&mut V, OccupiedError<'_, K, V, S>>
Tries to insert a key-value pair into the map, and returns a mutable reference to the value in the entry.
Refer to try_insert
for further details.
§Examples
let mut map = HashMap::new();
map.try_insert("foo", 0).unwrap();
assert!(map.try_insert("foo", 1).is_err());
Sourcepub fn remove<Q>(&mut self, k: &Q) -> Option<V>
pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
Removes a key from the map, returning the value at the key if the key was previously in the map. Keeps the allocated memory for reuse.
Refer to remove
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.remove("foo"), Some(0));
assert!(map.is_empty());
Examples found in repository?
More examples
230fn extract_image_materials(
231 mut material_instances: ResMut<RenderMaterialInstances>,
232 changed_meshes_query: Extract<
233 Query<
234 (Entity, &ViewVisibility, &ImageMaterial3d),
235 Or<(Changed<ViewVisibility>, Changed<ImageMaterial3d>)>,
236 >,
237 >,
238) {
239 let last_change_tick = material_instances.current_change_tick;
240
241 for (entity, view_visibility, material) in &changed_meshes_query {
242 if view_visibility.get() {
243 material_instances.instances.insert(
244 entity.into(),
245 RenderMaterialInstance {
246 asset_id: material.0.id().untyped(),
247 last_change_tick,
248 },
249 );
250 } else {
251 material_instances
252 .instances
253 .remove(&MainEntity::from(entity));
254 }
255 }
256}
257
258fn check_entities_needing_specialization(
259 needs_specialization: Query<
260 Entity,
261 (
262 Or<(
263 Changed<Mesh3d>,
264 AssetChanged<Mesh3d>,
265 Changed<ImageMaterial3d>,
266 AssetChanged<ImageMaterial3d>,
267 )>,
268 With<ImageMaterial3d>,
269 ),
270 >,
271 mut par_local: Local<Parallel<Vec<Entity>>>,
272 mut entities_needing_specialization: ResMut<EntitiesNeedingSpecialization<ImageMaterial>>,
273) {
274 entities_needing_specialization.clear();
275
276 needs_specialization
277 .par_iter()
278 .for_each(|entity| par_local.borrow_local_mut().push(entity));
279
280 par_local.drain_into(&mut entities_needing_specialization);
281}
282
283fn extract_image_materials_needing_specialization(
284 entities_needing_specialization: Extract<Res<EntitiesNeedingSpecialization<ImageMaterial>>>,
285 mut entity_specialization_ticks: ResMut<EntitySpecializationTicks>,
286 mut removed_mesh_material_components: Extract<RemovedComponents<ImageMaterial3d>>,
287 mut specialized_material_pipeline_cache: ResMut<SpecializedMaterialPipelineCache>,
288 views: Query<&ExtractedView>,
289 ticks: SystemChangeTick,
290) {
291 // Clean up any despawned entities, we do this first in case the removed material was re-added
292 // the same frame, thus will appear both in the removed components list and have been added to
293 // the `EntitiesNeedingSpecialization` collection by triggering the `Changed` filter
294 for entity in removed_mesh_material_components.read() {
295 entity_specialization_ticks.remove(&MainEntity::from(entity));
296 for view in views {
297 if let Some(cache) =
298 specialized_material_pipeline_cache.get_mut(&view.retained_view_entity)
299 {
300 cache.remove(&MainEntity::from(entity));
301 }
302 }
303 }
304
305 for entity in entities_needing_specialization.iter() {
306 // Update the entity's specialization tick with this run's tick
307 entity_specialization_ticks.insert((*entity).into(), ticks.this_run());
308 }
309}
Sourcepub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
Removes a key from the map, returning the stored key and value if the key was previously in the map. Keeps the allocated memory for reuse.
Refer to remove_entry
for further details.
§Examples
let mut map = HashMap::new();
map.insert("foo", 0);
assert_eq!(map.remove_entry("foo"), Some(("foo", 0)));
assert!(map.is_empty());
Sourcepub fn allocation_size(&self) -> usize
pub fn allocation_size(&self) -> usize
Returns the total amount of memory allocated internally by the hash set, in bytes.
Refer to allocation_size
for further details.
§Examples
let mut map = HashMap::new();
assert_eq!(map.allocation_size(), 0);
map.insert("foo", 0u32);
assert!(map.allocation_size() >= size_of::<&'static str>() + size_of::<u32>());
Sourcepub unsafe fn insert_unique_unchecked(
&mut self,
key: K,
value: V,
) -> (&K, &mut V)
pub unsafe fn insert_unique_unchecked( &mut self, key: K, value: V, ) -> (&K, &mut V)
Insert a key-value pair into the map without checking if the key already exists in the map.
Refer to insert_unique_unchecked
for further details.
§Safety
This operation is safe if a key does not exist in the map.
However, if a key exists in the map already, the behavior is unspecified: this operation may panic, loop forever, or any following operation with the map may panic, loop forever or return arbitrary result.
That said, this operation (and following operations) are guaranteed to not violate memory safety.
However this operation is still unsafe because the resulting HashMap
may be passed to unsafe code which does expect the map to behave
correctly, and would cause unsoundness as a result.
Sourcepub unsafe fn get_many_unchecked_mut<Q, const N: usize>(
&mut self,
keys: [&Q; N],
) -> [Option<&mut V>; N]
pub unsafe fn get_many_unchecked_mut<Q, const N: usize>( &mut self, keys: [&Q; N], ) -> [Option<&mut V>; N]
Attempts to get mutable references to N
values in the map at once, without validating that
the values are unique.
Refer to get_many_unchecked_mut
for further details.
Returns an array of length N
with the results of each query. None
will be used if
the key is missing.
For a safe alternative see get_many_mut
.
§Safety
Calling this method with overlapping keys is undefined behavior even if the resulting references are not used.
Sourcepub unsafe fn get_many_key_value_unchecked_mut<Q, const N: usize>(
&mut self,
keys: [&Q; N],
) -> [Option<(&K, &mut V)>; N]
pub unsafe fn get_many_key_value_unchecked_mut<Q, const N: usize>( &mut self, keys: [&Q; N], ) -> [Option<(&K, &mut V)>; N]
Attempts to get mutable references to N
values in the map at once, with immutable
references to the corresponding keys, without validating that the values are unique.
Refer to get_many_key_value_unchecked_mut
for further details.
Returns an array of length N
with the results of each query. None
will be returned if
any of the keys are missing.
For a safe alternative see get_many_key_value_mut
.
§Safety
Calling this method with overlapping keys is undefined behavior even if the resulting references are not used.
Methods from Deref<Target = HashMap<K, V, S>>§
Sourcepub fn hasher(&self) -> &S
pub fn hasher(&self) -> &S
Returns a reference to the map’s BuildHasher
.
§Examples
use hashbrown::HashMap;
use hashbrown::DefaultHashBuilder;
let hasher = DefaultHashBuilder::default();
let map: HashMap<i32, i32> = HashMap::with_hasher(hasher);
let hasher: &DefaultHashBuilder = map.hasher();
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the number of elements the map can hold without reallocating.
This number is a lower bound; the HashMap<K, V>
might be able to hold
more, but is guaranteed to be able to hold at least this many.
§Examples
use hashbrown::HashMap;
let map: HashMap<i32, i32> = HashMap::with_capacity(100);
assert_eq!(map.len(), 0);
assert!(map.capacity() >= 100);
Sourcepub fn keys(&self) -> Keys<'_, K, V> ⓘ
pub fn keys(&self) -> Keys<'_, K, V> ⓘ
An iterator visiting all keys in arbitrary order.
The iterator element type is &'a K
.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
assert_eq!(map.len(), 3);
let mut vec: Vec<&str> = Vec::new();
for key in map.keys() {
println!("{}", key);
vec.push(*key);
}
// The `Keys` iterator produces keys in arbitrary order, so the
// keys must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, ["a", "b", "c"]);
assert_eq!(map.len(), 3);
Sourcepub fn values(&self) -> Values<'_, K, V> ⓘ
pub fn values(&self) -> Values<'_, K, V> ⓘ
An iterator visiting all values in arbitrary order.
The iterator element type is &'a V
.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
assert_eq!(map.len(), 3);
let mut vec: Vec<i32> = Vec::new();
for val in map.values() {
println!("{}", val);
vec.push(*val);
}
// The `Values` iterator produces values in arbitrary order, so the
// values must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [1, 2, 3]);
assert_eq!(map.len(), 3);
Sourcepub fn values_mut(&mut self) -> ValuesMut<'_, K, V> ⓘ
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> ⓘ
An iterator visiting all values mutably in arbitrary order.
The iterator element type is &'a mut V
.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
for val in map.values_mut() {
*val = *val + 10;
}
assert_eq!(map.len(), 3);
let mut vec: Vec<i32> = Vec::new();
for val in map.values() {
println!("{}", val);
vec.push(*val);
}
// The `Values` iterator produces values in arbitrary order, so the
// values must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [11, 12, 13]);
assert_eq!(map.len(), 3);
Sourcepub fn iter(&self) -> Iter<'_, K, V> ⓘ
pub fn iter(&self) -> Iter<'_, K, V> ⓘ
An iterator visiting all key-value pairs in arbitrary order.
The iterator element type is (&'a K, &'a V)
.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
assert_eq!(map.len(), 3);
let mut vec: Vec<(&str, i32)> = Vec::new();
for (key, val) in map.iter() {
println!("key: {} val: {}", key, val);
vec.push((*key, *val));
}
// The `Iter` iterator produces items in arbitrary order, so the
// items must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
assert_eq!(map.len(), 3);
Sourcepub fn iter_mut(&mut self) -> IterMut<'_, K, V> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> ⓘ
An iterator visiting all key-value pairs in arbitrary order,
with mutable references to the values.
The iterator element type is (&'a K, &'a mut V)
.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
// Update all values
for (_, val) in map.iter_mut() {
*val *= 2;
}
assert_eq!(map.len(), 3);
let mut vec: Vec<(&str, i32)> = Vec::new();
for (key, val) in &map {
println!("key: {} val: {}", key, val);
vec.push((*key, *val));
}
// The `Iter` iterator produces items in arbitrary order, so the
// items must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [("a", 2), ("b", 4), ("c", 6)]);
assert_eq!(map.len(), 3);
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of elements in the map.
§Examples
use hashbrown::HashMap;
let mut a = HashMap::new();
assert_eq!(a.len(), 0);
a.insert(1, "a");
assert_eq!(a.len(), 1);
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the map contains no elements.
§Examples
use hashbrown::HashMap;
let mut a = HashMap::new();
assert!(a.is_empty());
a.insert(1, "a");
assert!(!a.is_empty());
Sourcepub fn drain(&mut self) -> Drain<'_, K, V, A> ⓘ
pub fn drain(&mut self) -> Drain<'_, K, V, A> ⓘ
Clears the map, returning all key-value pairs as an iterator. Keeps the allocated memory for reuse.
If the returned iterator is dropped before being fully consumed, it drops the remaining key-value pairs. The returned iterator keeps a mutable borrow on the vector to optimize its implementation.
§Examples
use hashbrown::HashMap;
let mut a = HashMap::new();
a.insert(1, "a");
a.insert(2, "b");
let capacity_before_drain = a.capacity();
for (k, v) in a.drain().take(1) {
assert!(k == 1 || k == 2);
assert!(v == "a" || v == "b");
}
// As we can see, the map is empty and contains no element.
assert!(a.is_empty() && a.len() == 0);
// But map capacity is equal to old one.
assert_eq!(a.capacity(), capacity_before_drain);
let mut a = HashMap::new();
a.insert(1, "a");
a.insert(2, "b");
{ // Iterator is dropped without being consumed.
let d = a.drain();
}
// But the map is empty even if we do not use Drain iterator.
assert!(a.is_empty());
Sourcepub fn retain<F>(&mut self, f: F)
pub fn retain<F>(&mut self, f: F)
Retains only the elements specified by the predicate. Keeps the allocated memory for reuse.
In other words, remove all pairs (k, v)
such that f(&k, &mut v)
returns false
.
The elements are visited in unsorted (and unspecified) order.
§Examples
use hashbrown::HashMap;
let mut map: HashMap<i32, i32> = (0..8).map(|x|(x, x*10)).collect();
assert_eq!(map.len(), 8);
map.retain(|&k, _| k % 2 == 0);
// We can see, that the number of elements inside map is changed.
assert_eq!(map.len(), 4);
let mut vec: Vec<(i32, i32)> = map.iter().map(|(&k, &v)| (k, v)).collect();
vec.sort_unstable();
assert_eq!(vec, [(0, 0), (2, 20), (4, 40), (6, 60)]);
Sourcepub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F, A> ⓘ
pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F, A> ⓘ
Drains elements which are true under the given predicate, and returns an iterator over the removed items.
In other words, move all pairs (k, v)
such that f(&k, &mut v)
returns true
out
into another iterator.
Note that extract_if
lets you mutate every value in the filter closure, regardless of
whether you choose to keep or remove it.
If the returned ExtractIf
is not exhausted, e.g. because it is dropped without iterating
or the iteration short-circuits, then the remaining elements will be retained.
Use retain()
with a negated predicate if you do not need the returned iterator.
Keeps the allocated memory for reuse.
§Examples
use hashbrown::HashMap;
let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
let drained: HashMap<i32, i32> = map.extract_if(|k, _v| k % 2 == 0).collect();
let mut evens = drained.keys().cloned().collect::<Vec<_>>();
let mut odds = map.keys().cloned().collect::<Vec<_>>();
evens.sort();
odds.sort();
assert_eq!(evens, vec![0, 2, 4, 6]);
assert_eq!(odds, vec![1, 3, 5, 7]);
let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x)).collect();
{ // Iterator is dropped without being consumed.
let d = map.extract_if(|k, _v| k % 2 != 0);
}
// ExtractIf was not exhausted, therefore no elements were drained.
assert_eq!(map.len(), 8);
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears the map, removing all key-value pairs. Keeps the allocated memory for reuse.
§Examples
use hashbrown::HashMap;
let mut a = HashMap::new();
a.insert(1, "a");
let capacity_before_clear = a.capacity();
a.clear();
// Map is empty.
assert!(a.is_empty());
// But map capacity is equal to old one.
assert_eq!(a.capacity(), capacity_before_clear);
Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Reserves capacity for at least additional
more elements to be inserted
in the HashMap
. The collection may reserve more space to avoid
frequent reallocations.
§Panics
Panics if the new capacity exceeds isize::MAX
bytes and abort
the program
in case of allocation error. Use try_reserve
instead
if you want to handle memory allocation failure.
§Examples
use hashbrown::HashMap;
let mut map: HashMap<&str, i32> = HashMap::new();
// Map is empty and doesn't allocate memory
assert_eq!(map.capacity(), 0);
map.reserve(10);
// And now map can hold at least 10 elements
assert!(map.capacity() >= 10);
Sourcepub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
Tries to reserve capacity for at least additional
more elements to be inserted
in the given HashMap<K,V>
. The collection may reserve more space to avoid
frequent reallocations.
§Errors
If the capacity overflows, or the allocator reports a failure, then an error is returned.
§Examples
use hashbrown::HashMap;
let mut map: HashMap<&str, isize> = HashMap::new();
// Map is empty and doesn't allocate memory
assert_eq!(map.capacity(), 0);
map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?");
// And now map can hold at least 10 elements
assert!(map.capacity() >= 10);
If the capacity overflows, or the allocator reports a failure, then an error is returned:
use hashbrown::HashMap;
use hashbrown::TryReserveError;
let mut map: HashMap<i32, i32> = HashMap::new();
match map.try_reserve(usize::MAX) {
Err(error) => match error {
TryReserveError::CapacityOverflow => {}
_ => panic!("TryReserveError::AllocError ?"),
},
_ => panic!(),
}
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Shrinks the capacity of the map as much as possible. It will drop down as much as possible while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
§Examples
use hashbrown::HashMap;
let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
map.insert(1, 2);
map.insert(3, 4);
assert!(map.capacity() >= 100);
map.shrink_to_fit();
assert!(map.capacity() >= 2);
Sourcepub fn shrink_to(&mut self, min_capacity: usize)
pub fn shrink_to(&mut self, min_capacity: usize)
Shrinks the capacity of the map with a lower limit. It will drop down no lower than the supplied limit while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
This function does nothing if the current capacity is smaller than the supplied minimum capacity.
§Examples
use hashbrown::HashMap;
let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
map.insert(1, 2);
map.insert(3, 4);
assert!(map.capacity() >= 100);
map.shrink_to(10);
assert!(map.capacity() >= 10);
map.shrink_to(0);
assert!(map.capacity() >= 2);
map.shrink_to(10);
assert!(map.capacity() >= 2);
Sourcepub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A>
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, A>
Gets the given key’s corresponding entry in the map for in-place manipulation.
§Examples
use hashbrown::HashMap;
let mut letters = HashMap::new();
for ch in "a short treatise on fungi".chars() {
let counter = letters.entry(ch).or_insert(0);
*counter += 1;
}
assert_eq!(letters[&'s'], 2);
assert_eq!(letters[&'t'], 3);
assert_eq!(letters[&'u'], 1);
assert_eq!(letters.get(&'y'), None);
Sourcepub fn entry_ref<'a, 'b, Q>(
&'a mut self,
key: &'b Q,
) -> EntryRef<'a, 'b, K, Q, V, S, A>
pub fn entry_ref<'a, 'b, Q>( &'a mut self, key: &'b Q, ) -> EntryRef<'a, 'b, K, Q, V, S, A>
Gets the given key’s corresponding entry by reference in the map for in-place manipulation.
§Examples
use hashbrown::HashMap;
let mut words: HashMap<String, usize> = HashMap::new();
let source = ["poneyland", "horseyland", "poneyland", "poneyland"];
for (i, &s) in source.iter().enumerate() {
let counter = words.entry_ref(s).or_insert(0);
*counter += 1;
}
assert_eq!(words["poneyland"], 3);
assert_eq!(words["horseyland"], 1);
Sourcepub fn get<Q>(&self, k: &Q) -> Option<&V>
pub fn get<Q>(&self, k: &Q) -> Option<&V>
Returns a reference to the value corresponding to the key.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get(&1), Some(&"a"));
assert_eq!(map.get(&2), None);
Sourcepub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
Returns the key-value pair corresponding to the supplied key.
The supplied key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
assert_eq!(map.get_key_value(&2), None);
Sourcepub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
pub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
The supplied key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert(1, "a");
let (k, v) = map.get_key_value_mut(&1).unwrap();
assert_eq!(k, &1);
assert_eq!(v, &mut "a");
*v = "b";
assert_eq!(map.get_key_value_mut(&1), Some((&1, &mut "b")));
assert_eq!(map.get_key_value_mut(&2), None);
Sourcepub fn contains_key<Q>(&self, k: &Q) -> bool
pub fn contains_key<Q>(&self, k: &Q) -> bool
Returns true
if the map contains a value for the specified key.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert(1, "a");
assert_eq!(map.contains_key(&1), true);
assert_eq!(map.contains_key(&2), false);
Sourcepub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
Returns a mutable reference to the value corresponding to the key.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
map.insert(1, "a");
if let Some(x) = map.get_mut(&1) {
*x = "b";
}
assert_eq!(map[&1], "b");
assert_eq!(map.get_mut(&2), None);
Sourcepub fn get_many_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<&mut V>; N]
pub fn get_many_mut<Q, const N: usize>( &mut self, ks: [&Q; N], ) -> [Option<&mut V>; N]
Attempts to get mutable references to N
values in the map at once.
Returns an array of length N
with the results of each query. For soundness, at most one
mutable reference will be returned to any value. None
will be used if the key is missing.
§Panics
Panics if any keys are overlapping.
§Examples
use hashbrown::HashMap;
let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Athenæum".to_string(), 1807);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
libraries.insert("Library of Congress".to_string(), 1800);
// Get Athenæum and Bodleian Library
let [Some(a), Some(b)] = libraries.get_many_mut([
"Athenæum",
"Bodleian Library",
]) else { panic!() };
// Assert values of Athenæum and Library of Congress
let got = libraries.get_many_mut([
"Athenæum",
"Library of Congress",
]);
assert_eq!(
got,
[
Some(&mut 1807),
Some(&mut 1800),
],
);
// Missing keys result in None
let got = libraries.get_many_mut([
"Athenæum",
"New York Public Library",
]);
assert_eq!(
got,
[
Some(&mut 1807),
None
]
);
use hashbrown::HashMap;
let mut libraries = HashMap::new();
libraries.insert("Athenæum".to_string(), 1807);
// Duplicate keys panic!
let got = libraries.get_many_mut([
"Athenæum",
"Athenæum",
]);
Sourcepub unsafe fn get_many_unchecked_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<&mut V>; N]
pub unsafe fn get_many_unchecked_mut<Q, const N: usize>( &mut self, ks: [&Q; N], ) -> [Option<&mut V>; N]
Attempts to get mutable references to N
values in the map at once, without validating that
the values are unique.
Returns an array of length N
with the results of each query. None
will be used if
the key is missing.
For a safe alternative see get_many_mut
.
§Safety
Calling this method with overlapping keys is undefined behavior even if the resulting references are not used.
§Examples
use hashbrown::HashMap;
let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Athenæum".to_string(), 1807);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
libraries.insert("Library of Congress".to_string(), 1800);
// SAFETY: The keys do not overlap.
let [Some(a), Some(b)] = (unsafe { libraries.get_many_unchecked_mut([
"Athenæum",
"Bodleian Library",
]) }) else { panic!() };
// SAFETY: The keys do not overlap.
let got = unsafe { libraries.get_many_unchecked_mut([
"Athenæum",
"Library of Congress",
]) };
assert_eq!(
got,
[
Some(&mut 1807),
Some(&mut 1800),
],
);
// SAFETY: The keys do not overlap.
let got = unsafe { libraries.get_many_unchecked_mut([
"Athenæum",
"New York Public Library",
]) };
// Missing keys result in None
assert_eq!(got, [Some(&mut 1807), None]);
Sourcepub fn get_many_key_value_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<(&K, &mut V)>; N]
pub fn get_many_key_value_mut<Q, const N: usize>( &mut self, ks: [&Q; N], ) -> [Option<(&K, &mut V)>; N]
Attempts to get mutable references to N
values in the map at once, with immutable
references to the corresponding keys.
Returns an array of length N
with the results of each query. For soundness, at most one
mutable reference will be returned to any value. None
will be used if the key is missing.
§Panics
Panics if any keys are overlapping.
§Examples
use hashbrown::HashMap;
let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Athenæum".to_string(), 1807);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
libraries.insert("Library of Congress".to_string(), 1800);
let got = libraries.get_many_key_value_mut([
"Bodleian Library",
"Herzogin-Anna-Amalia-Bibliothek",
]);
assert_eq!(
got,
[
Some((&"Bodleian Library".to_string(), &mut 1602)),
Some((&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691)),
],
);
// Missing keys result in None
let got = libraries.get_many_key_value_mut([
"Bodleian Library",
"Gewandhaus",
]);
assert_eq!(got, [Some((&"Bodleian Library".to_string(), &mut 1602)), None]);
use hashbrown::HashMap;
let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
// Duplicate keys result in panic!
let got = libraries.get_many_key_value_mut([
"Bodleian Library",
"Herzogin-Anna-Amalia-Bibliothek",
"Herzogin-Anna-Amalia-Bibliothek",
]);
Sourcepub unsafe fn get_many_key_value_unchecked_mut<Q, const N: usize>(
&mut self,
ks: [&Q; N],
) -> [Option<(&K, &mut V)>; N]
pub unsafe fn get_many_key_value_unchecked_mut<Q, const N: usize>( &mut self, ks: [&Q; N], ) -> [Option<(&K, &mut V)>; N]
Attempts to get mutable references to N
values in the map at once, with immutable
references to the corresponding keys, without validating that the values are unique.
Returns an array of length N
with the results of each query. None
will be returned if
any of the keys are missing.
For a safe alternative see get_many_key_value_mut
.
§Safety
Calling this method with overlapping keys is undefined behavior even if the resulting references are not used.
§Examples
use hashbrown::HashMap;
let mut libraries = HashMap::new();
libraries.insert("Bodleian Library".to_string(), 1602);
libraries.insert("Athenæum".to_string(), 1807);
libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
libraries.insert("Library of Congress".to_string(), 1800);
let got = libraries.get_many_key_value_mut([
"Bodleian Library",
"Herzogin-Anna-Amalia-Bibliothek",
]);
assert_eq!(
got,
[
Some((&"Bodleian Library".to_string(), &mut 1602)),
Some((&"Herzogin-Anna-Amalia-Bibliothek".to_string(), &mut 1691)),
],
);
// Missing keys result in None
let got = libraries.get_many_key_value_mut([
"Bodleian Library",
"Gewandhaus",
]);
assert_eq!(
got,
[
Some((&"Bodleian Library".to_string(), &mut 1602)),
None,
],
);
Sourcepub fn insert(&mut self, k: K, v: V) -> Option<V>
pub fn insert(&mut self, k: K, v: V) -> Option<V>
Inserts a key-value pair into the map.
If the map did not have this key present, None
is returned.
If the map did have this key present, the value is updated, and the old
value is returned. The key is not updated, though; this matters for
types that can be ==
without being identical. See the std::collections
module-level documentation for more.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
assert_eq!(map.insert(37, "a"), None);
assert_eq!(map.is_empty(), false);
map.insert(37, "b");
assert_eq!(map.insert(37, "c"), Some("b"));
assert_eq!(map[&37], "c");
Sourcepub unsafe fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V)
pub unsafe fn insert_unique_unchecked(&mut self, k: K, v: V) -> (&K, &mut V)
Insert a key-value pair into the map without checking if the key already exists in the map.
This operation is faster than regular insert, because it does not perform lookup before insertion.
This operation is useful during initial population of the map. For example, when constructing a map from another map, we know that keys are unique.
Returns a reference to the key and value just inserted.
§Safety
This operation is safe if a key does not exist in the map.
However, if a key exists in the map already, the behavior is unspecified: this operation may panic, loop forever, or any following operation with the map may panic, loop forever or return arbitrary result.
That said, this operation (and following operations) are guaranteed to not violate memory safety.
However this operation is still unsafe because the resulting HashMap
may be passed to unsafe code which does expect the map to behave
correctly, and would cause unsoundness as a result.
§Examples
use hashbrown::HashMap;
let mut map1 = HashMap::new();
assert_eq!(map1.insert(1, "a"), None);
assert_eq!(map1.insert(2, "b"), None);
assert_eq!(map1.insert(3, "c"), None);
assert_eq!(map1.len(), 3);
let mut map2 = HashMap::new();
for (key, value) in map1.into_iter() {
unsafe {
map2.insert_unique_unchecked(key, value);
}
}
let (key, value) = unsafe { map2.insert_unique_unchecked(4, "d") };
assert_eq!(key, &4);
assert_eq!(value, &mut "d");
*value = "e";
assert_eq!(map2[&1], "a");
assert_eq!(map2[&2], "b");
assert_eq!(map2[&3], "c");
assert_eq!(map2[&4], "e");
assert_eq!(map2.len(), 4);
Sourcepub fn try_insert(
&mut self,
key: K,
value: V,
) -> Result<&mut V, OccupiedError<'_, K, V, S, A>>
pub fn try_insert( &mut self, key: K, value: V, ) -> Result<&mut V, OccupiedError<'_, K, V, S, A>>
Tries to insert a key-value pair into the map, and returns a mutable reference to the value in the entry.
§Errors
If the map already had this key present, nothing is updated, and an error containing the occupied entry and the value is returned.
§Examples
Basic usage:
use hashbrown::HashMap;
use hashbrown::hash_map::OccupiedError;
let mut map = HashMap::new();
assert_eq!(map.try_insert(37, "a").unwrap(), &"a");
match map.try_insert(37, "b") {
Err(OccupiedError { entry, value }) => {
assert_eq!(entry.key(), &37);
assert_eq!(entry.get(), &"a");
assert_eq!(value, "b");
}
_ => panic!()
}
Sourcepub fn remove<Q>(&mut self, k: &Q) -> Option<V>
pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
Removes a key from the map, returning the value at the key if the key was previously in the map. Keeps the allocated memory for reuse.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
// The map is empty
assert!(map.is_empty() && map.capacity() == 0);
map.insert(1, "a");
assert_eq!(map.remove(&1), Some("a"));
assert_eq!(map.remove(&1), None);
// Now map holds none elements
assert!(map.is_empty());
Sourcepub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
Removes a key from the map, returning the stored key and value if the key was previously in the map. Keeps the allocated memory for reuse.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use hashbrown::HashMap;
let mut map = HashMap::new();
// The map is empty
assert!(map.is_empty() && map.capacity() == 0);
map.insert(1, "a");
assert_eq!(map.remove_entry(&1), Some((1, "a")));
assert_eq!(map.remove(&1), None);
// Now map hold none elements
assert!(map.is_empty());
Sourcepub fn allocation_size(&self) -> usize
pub fn allocation_size(&self) -> usize
Returns the total amount of memory allocated internally by the hash set, in bytes.
The returned number is informational only. It is intended to be primarily used for memory profiling.
Sourcepub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A>
pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S, A>
Creates a raw entry builder for the HashMap
.
Raw entries provide the lowest level of control for searching and manipulating a map. They must be manually initialized with a hash and then manually searched. After this, insertions into a vacant entry still require an owned key to be provided.
Raw entries are useful for such exotic situations as:
- Hash memoization
- Deferring the creation of an owned key until it is known to be required
- Using a search key that doesn’t work with the Borrow trait
- Using custom comparison logic without newtype wrappers
Because raw entries provide much more low-level control, it’s much easier
to put the HashMap
into an inconsistent state which, while memory-safe,
will cause the map to produce seemingly random results. Higher-level and
more foolproof APIs like entry
should be preferred when possible.
In particular, the hash used to initialized the raw entry must still be
consistent with the hash of the key that is ultimately stored in the entry.
This is because implementations of HashMap
may need to recompute hashes
when resizing, at which point only the keys are available.
Raw entries give mutable access to the keys. This must not be used to modify how the key would compare or hash, as the map will not re-evaluate where the key should go, meaning the keys may become “lost” if their location does not reflect their state. For instance, if you change a key so that the map now contains keys which compare equal, search may start acting erratically, with two keys randomly masking each other. Implementations are free to assume this doesn’t happen (within the limits of memory-safety).
§Examples
use core::hash::{BuildHasher, Hash};
use hashbrown::hash_map::{HashMap, RawEntryMut};
let mut map = HashMap::new();
map.extend([("a", 100), ("b", 200), ("c", 300)]);
fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
use core::hash::Hasher;
let mut state = hash_builder.build_hasher();
key.hash(&mut state);
state.finish()
}
// Existing key (insert and update)
match map.raw_entry_mut().from_key(&"a") {
RawEntryMut::Vacant(_) => unreachable!(),
RawEntryMut::Occupied(mut view) => {
assert_eq!(view.get(), &100);
let v = view.get_mut();
let new_v = (*v) * 10;
*v = new_v;
assert_eq!(view.insert(1111), 1000);
}
}
assert_eq!(map[&"a"], 1111);
assert_eq!(map.len(), 3);
// Existing key (take)
let hash = compute_hash(map.hasher(), &"c");
match map.raw_entry_mut().from_key_hashed_nocheck(hash, &"c") {
RawEntryMut::Vacant(_) => unreachable!(),
RawEntryMut::Occupied(view) => {
assert_eq!(view.remove_entry(), ("c", 300));
}
}
assert_eq!(map.raw_entry().from_key(&"c"), None);
assert_eq!(map.len(), 2);
// Nonexistent key (insert and update)
let key = "d";
let hash = compute_hash(map.hasher(), &key);
match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
RawEntryMut::Occupied(_) => unreachable!(),
RawEntryMut::Vacant(view) => {
let (k, value) = view.insert("d", 4000);
assert_eq!((*k, *value), ("d", 4000));
*value = 40000;
}
}
assert_eq!(map[&"d"], 40000);
assert_eq!(map.len(), 3);
match map.raw_entry_mut().from_hash(hash, |q| *q == key) {
RawEntryMut::Vacant(_) => unreachable!(),
RawEntryMut::Occupied(view) => {
assert_eq!(view.remove_entry(), ("d", 40000));
}
}
assert_eq!(map.get(&"d"), None);
assert_eq!(map.len(), 2);
Sourcepub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A>
pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S, A>
Creates a raw immutable entry builder for the HashMap
.
Raw entries provide the lowest level of control for searching and manipulating a map. They must be manually initialized with a hash and then manually searched.
This is useful for
- Hash memoization
- Using a search key that doesn’t work with the Borrow trait
- Using custom comparison logic without newtype wrappers
Unless you are in such a situation, higher-level and more foolproof APIs like
get
should be preferred.
Immutable raw entries have very limited use; you might instead want raw_entry_mut
.
§Examples
use core::hash::{BuildHasher, Hash};
use hashbrown::HashMap;
let mut map = HashMap::new();
map.extend([("a", 100), ("b", 200), ("c", 300)]);
fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
use core::hash::Hasher;
let mut state = hash_builder.build_hasher();
key.hash(&mut state);
state.finish()
}
for k in ["a", "b", "c", "d", "e", "f"] {
let hash = compute_hash(map.hasher(), k);
let v = map.get(&k).cloned();
let kv = v.as_ref().map(|v| (&k, v));
println!("Key: {} and value: {:?}", k, v);
assert_eq!(map.raw_entry().from_key(&k), kv);
assert_eq!(map.raw_entry().from_hash(hash, |q| *q == k), kv);
assert_eq!(map.raw_entry().from_key_hashed_nocheck(hash, &k), kv);
}
Trait Implementations§
Source§impl<'de, K, V, S> Deserialize<'de> for HashMap<K, V, S>where
HashMap<K, V, S>: Deserialize<'de>,
impl<'de, K, V, S> Deserialize<'de> for HashMap<K, V, S>where
HashMap<K, V, S>: Deserialize<'de>,
Source§fn deserialize<D>(
deserializer: D,
) -> Result<HashMap<K, V, S>, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn deserialize<D>(
deserializer: D,
) -> Result<HashMap<K, V, S>, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
Source§impl<K, V, S, T> Extend<T> for HashMap<K, V, S>
impl<K, V, S, T> Extend<T> for HashMap<K, V, S>
Source§fn extend<U>(&mut self, iter: U)where
U: IntoIterator<Item = T>,
fn extend<U>(&mut self, iter: U)where
U: IntoIterator<Item = T>,
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Source§impl<K, V, S> FromArg for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> FromArg for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§impl<K, V, S, T> FromIterator<T> for HashMap<K, V, S>where
HashMap<K, V, S>: FromIterator<T>,
impl<K, V, S, T> FromIterator<T> for HashMap<K, V, S>where
HashMap<K, V, S>: FromIterator<T>,
Source§impl<K, V, S> FromReflect for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> FromReflect for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§fn from_reflect(
reflect: &(dyn PartialReflect + 'static),
) -> Option<HashMap<K, V, S>>
fn from_reflect( reflect: &(dyn PartialReflect + 'static), ) -> Option<HashMap<K, V, S>>
Self
from a reflected value.Source§fn take_from_reflect(
reflect: Box<dyn PartialReflect>,
) -> Result<Self, Box<dyn PartialReflect>>
fn take_from_reflect( reflect: Box<dyn PartialReflect>, ) -> Result<Self, Box<dyn PartialReflect>>
Self
using,
constructing the value using from_reflect
if that fails. Read moreSource§impl<K, V, S> GetOwnership for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> GetOwnership for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§impl<K, V, S> GetTypeRegistration for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> GetTypeRegistration for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration
for this type.Source§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
Source§impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>where
&'a HashMap<K, V, S>: IntoIterator,
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>where
&'a HashMap<K, V, S>: IntoIterator,
Source§impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>where
&'a mut HashMap<K, V, S>: IntoIterator,
impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>where
&'a mut HashMap<K, V, S>: IntoIterator,
Source§impl<K, V, S> IntoIterator for HashMap<K, V, S>where
HashMap<K, V, S>: IntoIterator,
impl<K, V, S> IntoIterator for HashMap<K, V, S>where
HashMap<K, V, S>: IntoIterator,
Source§impl<K, V, S> IntoReturn for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> IntoReturn for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§impl<K, V, S> Map for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> Map for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§fn get(
&self,
key: &(dyn PartialReflect + 'static),
) -> Option<&(dyn PartialReflect + 'static)>
fn get( &self, key: &(dyn PartialReflect + 'static), ) -> Option<&(dyn PartialReflect + 'static)>
Source§fn get_mut(
&mut self,
key: &(dyn PartialReflect + 'static),
) -> Option<&mut (dyn PartialReflect + 'static)>
fn get_mut( &mut self, key: &(dyn PartialReflect + 'static), ) -> Option<&mut (dyn PartialReflect + 'static)>
Source§fn iter(
&self,
) -> Box<dyn Iterator<Item = (&(dyn PartialReflect + 'static), &(dyn PartialReflect + 'static))> + '_>
fn iter( &self, ) -> Box<dyn Iterator<Item = (&(dyn PartialReflect + 'static), &(dyn PartialReflect + 'static))> + '_>
Source§fn drain(&mut self) -> Vec<(Box<dyn PartialReflect>, Box<dyn PartialReflect>)>
fn drain(&mut self) -> Vec<(Box<dyn PartialReflect>, Box<dyn PartialReflect>)>
Source§fn retain(
&mut self,
f: &mut dyn FnMut(&(dyn PartialReflect + 'static), &mut (dyn PartialReflect + 'static)) -> bool,
)
fn retain( &mut self, f: &mut dyn FnMut(&(dyn PartialReflect + 'static), &mut (dyn PartialReflect + 'static)) -> bool, )
Source§fn to_dynamic_map(&self) -> DynamicMap
fn to_dynamic_map(&self) -> DynamicMap
DynamicMap
from this map.Source§fn insert_boxed(
&mut self,
key: Box<dyn PartialReflect>,
value: Box<dyn PartialReflect>,
) -> Option<Box<dyn PartialReflect>>
fn insert_boxed( &mut self, key: Box<dyn PartialReflect>, value: Box<dyn PartialReflect>, ) -> Option<Box<dyn PartialReflect>>
Source§fn remove(
&mut self,
key: &(dyn PartialReflect + 'static),
) -> Option<Box<dyn PartialReflect>>
fn remove( &mut self, key: &(dyn PartialReflect + 'static), ) -> Option<Box<dyn PartialReflect>>
Source§impl<K, V, S> MapEntities for HashMap<K, V, S>
impl<K, V, S> MapEntities for HashMap<K, V, S>
Source§fn map_entities<E>(&mut self, entity_mapper: &mut E)where
E: EntityMapper,
fn map_entities<E>(&mut self, entity_mapper: &mut E)where
E: EntityMapper,
Source§impl<K, V, S> PartialReflect for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> PartialReflect for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
Source§fn into_partial_reflect(self: Box<HashMap<K, V, S>>) -> Box<dyn PartialReflect>
fn into_partial_reflect(self: Box<HashMap<K, V, S>>) -> Box<dyn PartialReflect>
Source§fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
fn as_partial_reflect(&self) -> &(dyn PartialReflect + 'static)
Source§fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
fn as_partial_reflect_mut(&mut self) -> &mut (dyn PartialReflect + 'static)
Source§fn try_into_reflect(
self: Box<HashMap<K, V, S>>,
) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
fn try_into_reflect( self: Box<HashMap<K, V, S>>, ) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>
Source§fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
fn try_as_reflect(&self) -> Option<&(dyn Reflect + 'static)>
Source§fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
fn try_as_reflect_mut(&mut self) -> Option<&mut (dyn Reflect + 'static)>
Source§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
Source§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
Source§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
Source§fn reflect_owned(self: Box<HashMap<K, V, S>>) -> ReflectOwned
fn reflect_owned(self: Box<HashMap<K, V, S>>) -> ReflectOwned
Source§fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError>
Self
using reflection. Read moreSource§fn reflect_partial_eq(
&self,
value: &(dyn PartialReflect + 'static),
) -> Option<bool>
fn reflect_partial_eq( &self, value: &(dyn PartialReflect + 'static), ) -> Option<bool>
Source§fn apply(&mut self, value: &(dyn PartialReflect + 'static))
fn apply(&mut self, value: &(dyn PartialReflect + 'static))
Source§fn try_apply(
&mut self,
value: &(dyn PartialReflect + 'static),
) -> Result<(), ApplyError>
fn try_apply( &mut self, value: &(dyn PartialReflect + 'static), ) -> Result<(), ApplyError>
Source§fn to_dynamic(&self) -> Box<dyn PartialReflect>
fn to_dynamic(&self) -> Box<dyn PartialReflect>
Source§fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
fn reflect_clone_and_take<T>(&self) -> Result<T, ReflectCloneError>
PartialReflect
, combines reflect_clone
and
take
in a useful fashion, automatically constructing an appropriate
ReflectCloneError
if the downcast fails. Read moreSource§fn reflect_hash(&self) -> Option<u64>
fn reflect_hash(&self) -> Option<u64>
Source§fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
Source§fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
Source§impl<K, V> PreHashMapExt<K, V> for HashMap<Hashed<K>, V, PassHash>
impl<K, V> PreHashMapExt<K, V> for HashMap<Hashed<K>, V, PassHash>
Source§fn get_or_insert_with<F>(&mut self, key: &Hashed<K>, func: F) -> &mut Vwhere
F: FnOnce() -> V,
fn get_or_insert_with<F>(&mut self, key: &Hashed<K>, func: F) -> &mut Vwhere
F: FnOnce() -> V,
key
using the pre-computed hash first.
If the PreHashMap
does not already contain the key
, it will clone it and insert
the value returned by func
.Source§impl<K, V, S> Reflect for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> Reflect for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
Source§fn into_any(self: Box<HashMap<K, V, S>>) -> Box<dyn Any>
fn into_any(self: Box<HashMap<K, V, S>>) -> Box<dyn Any>
Box<dyn Any>
. Read moreSource§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut dyn Any
. Read moreSource§fn into_reflect(self: Box<HashMap<K, V, S>>) -> Box<dyn Reflect>
fn into_reflect(self: Box<HashMap<K, V, S>>) -> Box<dyn Reflect>
Source§fn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
Source§fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
Source§impl<K, V, S> Serialize for HashMap<K, V, S>
impl<K, V, S> Serialize for HashMap<K, V, S>
Source§fn serialize<T>(
&self,
serializer: T,
) -> Result<<T as Serializer>::Ok, <T as Serializer>::Error>where
T: Serializer,
fn serialize<T>(
&self,
serializer: T,
) -> Result<<T as Serializer>::Ok, <T as Serializer>::Error>where
T: Serializer,
Source§impl<V> TypeIdMapExt<V> for HashMap<TypeId, V, NoOpHash>
impl<V> TypeIdMapExt<V> for HashMap<TypeId, V, NoOpHash>
Source§fn insert_type<T>(&mut self, v: V) -> Option<V>where
T: 'static + ?Sized,
fn insert_type<T>(&mut self, v: V) -> Option<V>where
T: 'static + ?Sized,
T
. Read moreSource§fn get_type<T>(&self) -> Option<&V>where
T: 'static + ?Sized,
fn get_type<T>(&self) -> Option<&V>where
T: 'static + ?Sized,
T
, if one exists.Source§fn get_type_mut<T>(&mut self) -> Option<&mut V>where
T: 'static + ?Sized,
fn get_type_mut<T>(&mut self) -> Option<&mut V>where
T: 'static + ?Sized,
T
, if one exists.Source§fn remove_type<T>(&mut self) -> Option<V>where
T: 'static + ?Sized,
fn remove_type<T>(&mut self) -> Option<V>where
T: 'static + ?Sized,
T
from the map, returning the value for this
key if it was previously present.Source§impl<K, V, S> TypePath for HashMap<K, V, S>
impl<K, V, S> TypePath for HashMap<K, V, S>
Source§fn type_path() -> &'static str
fn type_path() -> &'static str
Source§fn short_type_path() -> &'static str
fn short_type_path() -> &'static str
Source§fn type_ident() -> Option<&'static str>
fn type_ident() -> Option<&'static str>
Source§fn crate_name() -> Option<&'static str>
fn crate_name() -> Option<&'static str>
Source§impl<K, V, S> Typed for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> Typed for HashMap<K, V, S>where
K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash,
V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration,
S: TypePath + BuildHasher + Default + Send + Sync,
impl<K, V, S> Eq for HashMap<K, V, S>
Auto Trait Implementations§
impl<K, V, S> Freeze for HashMap<K, V, S>where
S: Freeze,
impl<K, V, S> RefUnwindSafe for HashMap<K, V, S>
impl<K, V, S> Send for HashMap<K, V, S>
impl<K, V, S> Sync for HashMap<K, V, S>
impl<K, V, S> Unpin for HashMap<K, V, S>
impl<K, V, S> UnwindSafe for HashMap<K, V, S>
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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 Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
Source§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path
.Source§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
Source§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident
.Source§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name
.Source§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
Source§impl<T> DynamicTyped for Twhere
T: Typed,
impl<T> DynamicTyped for Twhere
T: Typed,
Source§fn reflect_type_info(&self) -> &'static TypeInfo
fn reflect_type_info(&self) -> &'static TypeInfo
Typed::type_info
.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.Source§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self
using default()
.
Source§impl<T> GetPath for T
impl<T> GetPath for T
Source§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p>, ) -> Result<&(dyn PartialReflect + 'static), ReflectPathError<'p>>
path
. Read moreSource§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p>, ) -> Result<&mut (dyn PartialReflect + 'static), ReflectPathError<'p>>
path
. Read moreSource§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>,
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moreSource§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>,
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moreSource§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> InitializeFromFunction<T> for T
impl<T> InitializeFromFunction<T> for T
Source§fn initialize_from_function(f: fn() -> T) -> T
fn initialize_from_function(f: fn() -> T) -> T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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 moreSource§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
Source§fn into_result(self) -> Result<T, RunSystemError>
fn into_result(self) -> Result<T, RunSystemError>
Source§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian()
.Source§impl<T> Serialize for T
impl<T> Serialize for T
fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>
fn do_erased_serialize( &self, serializer: &mut dyn Serializer, ) -> Result<(), ErrorImpl>
Source§impl<Ret> SpawnIfAsync<(), Ret> for Ret
impl<Ret> SpawnIfAsync<(), Ret> for Ret
Source§impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
impl<T, O> SuperFrom<T> for Owhere
O: From<T>,
Source§fn super_from(input: T) -> O
fn super_from(input: T) -> O
Source§impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
impl<T, O, M> SuperInto<O, M> for Twhere
O: SuperFrom<T, M>,
Source§fn super_into(self) -> O
fn super_into(self) -> O
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.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
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.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
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.