|
4 | 4 | )] |
5 | 5 | use alloc::{ |
6 | 6 | boxed::Box, |
7 | | - collections::{BTreeMap, BTreeSet}, |
| 7 | + collections::BTreeSet, |
8 | 8 | format, |
9 | 9 | string::{String, ToString}, |
10 | 10 | vec, |
11 | 11 | vec::Vec, |
12 | 12 | }; |
13 | | -use bevy_platform::collections::{HashMap, HashSet}; |
| 13 | +use bevy_platform::{ |
| 14 | + collections::{HashMap, HashSet}, |
| 15 | + hash::FixedHasher, |
| 16 | +}; |
14 | 17 | use bevy_utils::{default, TypeIdMap}; |
15 | 18 | use core::{ |
16 | 19 | any::{Any, TypeId}, |
17 | 20 | fmt::{Debug, Write}, |
18 | 21 | }; |
19 | 22 | use fixedbitset::FixedBitSet; |
| 23 | +use indexmap::IndexMap; |
20 | 24 | use log::{info, warn}; |
21 | 25 | use pass::ScheduleBuildPassObj; |
22 | 26 | use thiserror::Error; |
@@ -465,7 +469,7 @@ impl Schedule { |
465 | 469 |
|
466 | 470 | /// Remove a custom build pass. |
467 | 471 | pub fn remove_build_pass<T: ScheduleBuildPass>(&mut self) { |
468 | | - self.graph.passes.remove(&TypeId::of::<T>()); |
| 472 | + self.graph.passes.shift_remove(&TypeId::of::<T>()); |
469 | 473 | } |
470 | 474 |
|
471 | 475 | /// Changes miscellaneous build settings. |
@@ -697,7 +701,7 @@ pub struct ScheduleGraph { |
697 | 701 | anonymous_sets: usize, |
698 | 702 | changed: bool, |
699 | 703 | settings: ScheduleBuildSettings, |
700 | | - passes: BTreeMap<TypeId, Box<dyn ScheduleBuildPassObj>>, |
| 704 | + passes: IndexMap<TypeId, Box<dyn ScheduleBuildPassObj>, FixedHasher>, |
701 | 705 | } |
702 | 706 |
|
703 | 707 | impl ScheduleGraph { |
@@ -1586,14 +1590,17 @@ pub struct ScheduleNotInitialized; |
1586 | 1590 |
|
1587 | 1591 | #[cfg(test)] |
1588 | 1592 | mod tests { |
| 1593 | + use alloc::{vec, vec::Vec}; |
| 1594 | + use core::any::TypeId; |
| 1595 | + |
1589 | 1596 | use bevy_ecs_macros::ScheduleLabel; |
1590 | 1597 |
|
1591 | 1598 | use crate::{ |
1592 | 1599 | error::{ignore, panic, DefaultErrorHandler, Result}, |
1593 | 1600 | prelude::{ApplyDeferred, IntoSystemSet, Res, Resource}, |
1594 | 1601 | schedule::{ |
1595 | | - tests::ResMut, IntoScheduleConfigs, Schedule, ScheduleBuildSettings, |
1596 | | - ScheduleCleanupPolicy, SystemSet, |
| 1602 | + passes::AutoInsertApplyDeferredPass, tests::ResMut, IntoScheduleConfigs, Schedule, |
| 1603 | + ScheduleBuildPass, ScheduleBuildSettings, ScheduleCleanupPolicy, SystemSet, |
1597 | 1604 | }, |
1598 | 1605 | system::Commands, |
1599 | 1606 | world::World, |
@@ -2571,4 +2578,55 @@ mod tests { |
2571 | 2578 | let conflicts = schedule.graph().conflicting_systems(); |
2572 | 2579 | assert!(conflicts.is_empty()); |
2573 | 2580 | } |
| 2581 | + |
| 2582 | + #[test] |
| 2583 | + fn build_pass_iteration_order() { |
| 2584 | + #[derive(Debug)] |
| 2585 | + struct Pass<const N: usize>; |
| 2586 | + |
| 2587 | + impl<const N: usize> ScheduleBuildPass for Pass<N> { |
| 2588 | + type EdgeOptions = (); |
| 2589 | + fn add_dependency( |
| 2590 | + &mut self, |
| 2591 | + _from: crate::schedule::NodeId, |
| 2592 | + _to: crate::schedule::NodeId, |
| 2593 | + _options: Option<&Self::EdgeOptions>, |
| 2594 | + ) { |
| 2595 | + } |
| 2596 | + fn build( |
| 2597 | + &mut self, |
| 2598 | + _world: &mut World, |
| 2599 | + _graph: &mut super::ScheduleGraph, |
| 2600 | + _dependency_flattened: &mut crate::schedule::graph::Dag<crate::schedule::SystemKey>, |
| 2601 | + ) -> core::result::Result<(), crate::schedule::ScheduleBuildError> { |
| 2602 | + Ok(()) |
| 2603 | + } |
| 2604 | + fn collapse_set( |
| 2605 | + &mut self, |
| 2606 | + _set: crate::schedule::SystemSetKey, |
| 2607 | + _systems: &bevy_platform::collections::HashSet<crate::schedule::SystemKey>, |
| 2608 | + _dependency_flattening: &crate::schedule::graph::DiGraph<crate::schedule::NodeId>, |
| 2609 | + ) -> impl Iterator<Item = (crate::schedule::NodeId, crate::schedule::NodeId)> |
| 2610 | + { |
| 2611 | + core::iter::empty() |
| 2612 | + } |
| 2613 | + } |
| 2614 | + |
| 2615 | + let mut schedule = Schedule::default(); |
| 2616 | + schedule.add_build_pass(Pass::<0>); |
| 2617 | + schedule.add_build_pass(Pass::<1>); |
| 2618 | + schedule.add_build_pass(Pass::<2>); |
| 2619 | + |
| 2620 | + let pass_order: Vec<TypeId> = schedule.graph().passes.keys().cloned().collect(); |
| 2621 | + |
| 2622 | + assert_eq!( |
| 2623 | + pass_order, |
| 2624 | + vec![ |
| 2625 | + TypeId::of::<AutoInsertApplyDeferredPass>(), |
| 2626 | + TypeId::of::<Pass<0>>(), |
| 2627 | + TypeId::of::<Pass<1>>(), |
| 2628 | + TypeId::of::<Pass<2>>() |
| 2629 | + ] |
| 2630 | + ); |
| 2631 | + } |
2574 | 2632 | } |
0 commit comments