1use crate::scene::facets::FacetId;
6use crate::scene::layout::ArrangerPtr;
7use crate::scene::scene::Scene;
8use crate::{IdFromRaw, IdGenerator2, Size};
9use std::any::Any;
10use std::collections::HashMap;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct GroupId(u64);
15
16impl GroupId {
17 pub(crate) fn new() -> Self {
19 IdGenerator2::<GroupId>::next().expect("group_id")
20 }
21}
22
23impl IdFromRaw for GroupId {
24 fn from_raw(id: u64) -> GroupId {
25 GroupId(id)
26 }
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30pub(crate) enum GroupMember {
31 Facet(FacetId),
32 Group(GroupId),
33}
34
35pub type GroupMemberData = Box<dyn Any>;
38
39impl GroupMember {
40 fn is_facet(&self, facet_id: FacetId) -> bool {
41 match self {
42 GroupMember::Group(_) => false,
43 GroupMember::Facet(member_facet_id) => *member_facet_id == facet_id,
44 }
45 }
46}
47
48#[derive(Debug)]
49pub(crate) struct GroupEntry {
50 member: GroupMember,
51 member_data: Option<GroupMemberData>,
52}
53
54#[derive(Debug)]
55pub(crate) struct Group {
56 #[allow(unused)]
58 pub id: GroupId,
59 #[allow(unused)]
61 pub label: String,
62 pub members: Vec<GroupEntry>,
63 pub arranger: Option<ArrangerPtr>,
64}
65
66#[derive(Debug)]
67pub(crate) struct GroupMap {
68 root_group_id: Option<GroupId>,
69 map: HashMap<GroupId, Group>,
70}
71
72impl GroupMap {
73 pub fn new() -> Self {
74 let map = HashMap::new();
75 Self { root_group_id: None, map }
76 }
77
78 pub fn get_root_group_id(&self) -> GroupId {
79 self.root_group_id.expect("root_group_id")
80 }
81
82 pub fn add_facet_to_group(
83 &mut self,
84 facet_id: FacetId,
85 group_id: GroupId,
86 member_data: Option<GroupMemberData>,
87 ) {
88 let group = self.map.get_mut(&group_id).expect("group");
89
90 group.members.push(GroupEntry { member: GroupMember::Facet(facet_id), member_data });
91 }
92
93 pub fn remove_facet_from_group(&mut self, facet_id: FacetId, group_id: GroupId) {
94 let group = self.map.get_mut(&group_id).expect("group");
95 group.members.retain(|entry| !entry.member.is_facet(facet_id));
96 }
97
98 pub fn group_members(&self, group_id: GroupId) -> Vec<GroupMember> {
99 self.map
100 .get(&group_id)
101 .expect("group_id")
102 .members
103 .iter()
104 .map(|entry| entry.member)
105 .collect()
106 }
107
108 pub(crate) fn group_member_data(&self, group_id: GroupId) -> Vec<&Option<GroupMemberData>> {
109 let member_data = self
110 .map
111 .get(&group_id)
112 .expect("group_id")
113 .members
114 .iter()
115 .map(|entry| &entry.member_data)
116 .collect();
117 member_data
118 }
119
120 pub fn group_arranger(&self, group_id: GroupId) -> Option<&ArrangerPtr> {
121 self.map.get(&group_id).and_then(|group| group.arranger.as_ref())
122 }
123
124 pub fn set_group_arranger(&mut self, group_id: GroupId, group_arranger: ArrangerPtr) {
125 let group = self.map.get_mut(&group_id).expect("group");
126 group.arranger = Some(group_arranger);
127 }
128
129 pub fn start_group(
130 &mut self,
131 group_id: GroupId,
132 label: &str,
133 arranger: ArrangerPtr,
134 parent: Option<&GroupId>,
135 member_data: Option<GroupMemberData>,
136 ) {
137 if self.root_group_id.is_none() {
138 self.root_group_id = Some(group_id);
139 }
140 let group = Group {
141 id: group_id,
142 label: String::from(label),
143 members: Vec::new(),
144 arranger: Some(arranger),
145 };
146 self.map.insert(group_id, group);
147 if let Some(parent) = parent {
148 let group = self.map.get_mut(&parent).expect("group");
149 group.members.push(GroupEntry { member: GroupMember::Group(group_id), member_data });
150 }
151 }
152
153 fn calculate_size_map_internal(
154 &self,
155 target_size: &Size,
156 scene: &Scene,
157 group_id: &GroupId,
158 size_map: &mut HashMap<GroupMember, Size>,
159 ) -> Size {
160 let group_members = self.group_members(*group_id);
161 let mut member_sizes = Vec::new();
162 for member in group_members.iter() {
163 match member {
164 GroupMember::Group(member_group_id) => {
165 let size = self.calculate_size_map_internal(
166 target_size,
167 scene,
168 &member_group_id,
169 size_map,
170 );
171 size_map.insert(*member, size);
172 member_sizes.push(size);
173 }
174 GroupMember::Facet(member_facet_id) => {
175 let size = scene.calculate_facet_size(&member_facet_id, *target_size);
176 member_sizes.push(size);
177 size_map.insert(*member, size);
178 }
179 }
180 }
181 let optional_arranger = self.group_arranger(*group_id);
182 if let Some(arranger) = optional_arranger {
183 let member_data = self.group_member_data(*group_id);
184 let mut mut_sizes = member_sizes.clone();
185 let arranged_size = arranger.calculate_size(*target_size, &mut mut_sizes, &member_data);
186 for ((member_id, member_size), new_member_size) in
187 group_members.iter().zip(member_sizes.iter()).zip(mut_sizes.iter())
188 {
189 if member_size != new_member_size {
190 size_map.insert(*member_id, *new_member_size);
191 }
192 }
193 arranged_size
194 } else {
195 panic!("need an arranger");
196 }
197 }
198
199 pub fn calculate_size_map(
200 &self,
201 target_size: Size,
202 scene: &Scene,
203 ) -> HashMap<GroupMember, Size> {
204 let mut size_map = HashMap::new();
205 let root_group_id = self.root_group_id.expect("root_group_id");
206 let root_size =
207 self.calculate_size_map_internal(&target_size, scene, &root_group_id, &mut size_map);
208 size_map.insert(GroupMember::Group(root_group_id), root_size);
209 size_map
210 }
211}