1use crate::errors::ser::Error as SerError;
3use havok_serde::HavokClass;
4use indexmap::IndexMap;
5
6pub trait HavokSort {
8 type Error;
9
10 fn sort_for_bytes(&mut self);
19
20 fn sort_for_xml(&mut self) -> Result<usize, Self::Error>;
28}
29
30impl<V> HavokSort for IndexMap<usize, V>
31where
32 V: HavokClass,
33{
34 type Error = SerError;
35
36 fn sort_for_bytes(&mut self) {
37 fn collect_deps<V>(
38 classes: &mut IndexMap<usize, V>,
39 key: usize,
40 sorted_keys: &mut Vec<usize>,
41 ) where
42 V: HavokClass,
43 {
44 if sorted_keys.contains(&key) {
45 return;
46 }
47
48 let current_index = match classes.get_index_of(&key) {
49 Some(index) => index,
50 None => return, };
52
53 sorted_keys.push(key);
54 classes.swap_indices(sorted_keys.len().saturating_sub(1), current_index);
55
56 if let Some(class) = classes.get(&key) {
57 let deps = class.deps_indexes();
58
59 #[cfg(feature = "tracing")]
60 tracing::trace!("index = {key}, deps_indexes = {deps:?}");
61
62 for dep_key in deps {
63 collect_deps(classes, dep_key, sorted_keys);
64 }
65 }
66 }
67
68 if self.is_empty() {
69 return;
70 }
71
72 let &root_key = match self.keys().min() {
73 Some(min) => min,
74 None => return,
75 };
76
77 let mut sorted_keys = Vec::with_capacity(self.len());
78 collect_deps(self, root_key, &mut sorted_keys);
79
80 #[cfg(feature = "tracing")]
81 tracing::trace!("sorted_keys = {:?}", sorted_keys);
82 }
83
84 fn sort_for_xml(&mut self) -> Result<usize, Self::Error> {
85 fn collect_deps<V>(
87 classes: &IndexMap<usize, V>,
88 key: usize,
89 class: &V,
90 sorted: &mut Vec<usize>,
91 ) where
92 V: HavokClass,
93 {
94 if sorted.contains(&key) {
95 return;
96 }
97
98 let deps = class.deps_indexes();
99 #[cfg(feature = "tracing")]
100 tracing::trace!("index = {key}, deps_indexes = {deps:?}");
101
102 for dep_key in deps {
103 if let Some(dep_class) = classes.get(&dep_key) {
104 collect_deps(classes, dep_key, dep_class, sorted);
105 }
106 }
107
108 sorted.push(key);
109 }
110
111 let mut sorted_keys = Vec::new();
112 let (&root_key, root_class) = self
113 .keys()
114 .min()
115 .and_then(|min| self.get_key_value(min))
116 .ok_or_else(|| SerError::Message {
117 msg: "Missing top pointer.".to_owned(),
118 })?;
119 collect_deps(self, root_key, root_class, &mut sorted_keys);
120
121 #[cfg(feature = "tracing")]
122 tracing::trace!("sorted_keys = {sorted_keys:?}");
123 let mut sorted_classes = Self::with_capacity(self.len());
124 for index in &sorted_keys {
125 if let Some(class) = self.swap_remove(index) {
126 sorted_classes.insert(*index, class);
127 }
128 }
129 *self = sorted_classes;
130 Ok(root_key)
131 }
132}