ck3_history_extractor/structures/
mod.rs1use std::{
2 any::type_name,
3 hash::{Hash, Hasher},
4};
5
6use super::{
7 game_data::{GameData, Localizable, LocalizationError},
8 parser::{GameObjectMap, GameRef, GameState, ParsingError},
9 types::{GameId, GameString, Wrapper, WrapperMut},
10};
11
12mod player;
14use derive_more::From;
15pub use player::Player;
16
17mod character;
19pub use character::Character;
20
21mod faith;
23pub use faith::Faith;
24
25mod culture;
27pub use culture::Culture;
28
29mod dynasty;
31pub use dynasty::Dynasty;
32
33mod house;
34pub use house::House;
35
36mod memory;
38pub use memory::Memory;
39
40mod title;
42use serde::Serialize;
43pub use title::Title;
44
45mod lineage;
47pub use lineage::LineageNode;
48
49mod artifact;
51pub use artifact::Artifact;
52
53pub trait FromGameObject: GameObjectDerived {
54 fn from_game_object(
55 base: &GameObjectMap,
56 game_state: &mut GameState,
57 ) -> Result<Self, ParsingError>;
58
59 #[allow(unused_variables)]
60 fn finalize(&mut self, reference: &GameRef<Self>) {}
61}
62
63pub trait GameObjectDerived: Sized {
67 fn get_name(&self) -> GameString;
70
71 fn get_references<E: From<EntityRef>, C: Extend<E>>(&self, collection: &mut C);
73}
74
75#[derive(Serialize, Debug)]
76pub struct GameObjectEntity<T: GameObjectDerived> {
77 id: GameId,
78 #[serde(flatten)]
85 entity: Option<T>,
86}
87
88impl<T: GameObjectDerived + FromGameObject> GameObjectEntity<T> {
89 pub fn new(id: GameId) -> Self {
90 Self { id, entity: None }
91 }
92
93 pub fn get_id(&self) -> GameId {
94 self.id
95 }
96
97 pub fn get_unique_identifier(&self) -> (GameId, &'static str) {
100 (self.get_id(), type_name::<T>())
101 }
102
103 pub fn init(
104 &mut self,
105 base: &GameObjectMap,
106 game_state: &mut GameState,
107 ) -> Result<(), ParsingError> {
108 self.entity = Some(T::from_game_object(base, game_state)?);
109 Ok(())
110 }
111
112 pub fn inner(&self) -> Option<&T> {
113 self.entity.as_ref()
114 }
115
116 pub fn inner_mut(&mut self) -> Option<&mut T> {
117 self.entity.as_mut()
118 }
119
120 pub fn replace(&mut self, entity: T) {
121 self.entity.replace(entity);
122 }
123}
124
125impl<T: GameObjectDerived + FromGameObject> PartialEq for GameObjectEntity<T> {
126 fn eq(&self, other: &Self) -> bool {
127 self.get_unique_identifier() == other.get_unique_identifier()
128 }
129}
130
131impl<T: GameObjectDerived + FromGameObject> Eq for GameObjectEntity<T> {}
132
133impl<T: GameObjectDerived + FromGameObject> Hash for GameObjectEntity<T> {
134 fn hash<H: Hasher>(&self, state: &mut H) {
135 self.get_unique_identifier().hash(state);
136 }
137}
138
139impl<T: Localizable + GameObjectDerived + FromGameObject> Localizable for GameRef<T> {
140 fn localize(&mut self, localization: &GameData) -> Result<(), LocalizationError> {
141 if let Some(entity) = self.get_internal_mut().entity.as_mut() {
142 entity.finalize(self);
143 entity.localize(localization)
144 } else {
145 Ok(())
146 }
147 }
148}
149
150impl<T: GameObjectDerived + FromGameObject> PartialEq for GameRef<T> {
151 fn eq(&self, other: &Self) -> bool {
152 if let Ok(a) = self.try_get_internal() {
153 if let Ok(b) = other.try_get_internal() {
154 a.get_unique_identifier() == b.get_unique_identifier()
155 } else {
156 false
157 }
158 } else {
159 false
160 }
161 }
162}
163
164impl<T: GameObjectDerived + FromGameObject> Eq for GameRef<T> {}
165
166impl<T: GameObjectDerived + FromGameObject> Hash for GameRef<T> {
167 fn hash<H: Hasher>(&self, state: &mut H) {
168 if let Ok(internal) = self.try_get_internal() {
169 internal.get_unique_identifier().hash(state);
170 }
171 }
172}
173
174#[derive(From, PartialEq, Eq)]
175pub enum EntityRef {
176 Character(GameRef<Character>),
177 Culture(GameRef<Culture>),
178 Dynasty(GameRef<Dynasty>),
179 House(GameRef<House>),
180 Faith(GameRef<Faith>),
181 Title(GameRef<Title>),
182 Memory(GameRef<Memory>),
183 Artifact(GameRef<Artifact>),
184}
185
186impl Hash for EntityRef {
187 fn hash<H: Hasher>(&self, state: &mut H) {
188 match self {
189 EntityRef::Character(char) => char.get_internal().hash(state),
190 EntityRef::Culture(cul) => cul.get_internal().hash(state),
191 EntityRef::Dynasty(dynasty) => dynasty.get_internal().hash(state),
192 EntityRef::House(house) => house.get_internal().hash(state),
193 EntityRef::Faith(faith) => faith.get_internal().hash(state),
194 EntityRef::Title(title) => title.get_internal().hash(state),
195 EntityRef::Memory(mem) => mem.get_internal().hash(state),
196 EntityRef::Artifact(art) => art.get_internal().hash(state),
197 }
198 }
199}
200
201impl GameObjectDerived for EntityRef {
202 fn get_name(&self) -> GameString {
203 match self {
204 EntityRef::Character(char) => char.get_internal().inner().unwrap().get_name(),
205 EntityRef::Culture(cul) => cul.get_internal().inner().unwrap().get_name(),
206 EntityRef::Dynasty(dynasty) => dynasty.get_internal().inner().unwrap().get_name(),
207 EntityRef::House(house) => house.get_internal().inner().unwrap().get_name(),
208 EntityRef::Faith(faith) => faith.get_internal().inner().unwrap().get_name(),
209 EntityRef::Title(title) => title.get_internal().inner().unwrap().get_name(),
210 EntityRef::Memory(mem) => mem.get_internal().inner().unwrap().get_name(),
211 EntityRef::Artifact(art) => art.get_internal().inner().unwrap().get_name(),
212 }
213 }
214
215 fn get_references<E: From<EntityRef>, C: Extend<E>>(&self, collection: &mut C) {
216 match self {
217 EntityRef::Character(char) => char
218 .get_internal()
219 .inner()
220 .map(|v| v.get_references(collection)),
221 EntityRef::Culture(cul) => cul
222 .get_internal()
223 .inner()
224 .map(|v| v.get_references(collection)),
225 EntityRef::Dynasty(dynasty) => dynasty
226 .get_internal()
227 .inner()
228 .map(|v| v.get_references(collection)),
229 EntityRef::House(house) => house
230 .get_internal()
231 .inner()
232 .map(|v| v.get_references(collection)),
233 EntityRef::Faith(faith) => faith
234 .get_internal()
235 .inner()
236 .map(|v| v.get_references(collection)),
237 EntityRef::Title(title) => title
238 .get_internal()
239 .inner()
240 .map(|v| v.get_references(collection)),
241 EntityRef::Memory(mem) => mem
242 .get_internal()
243 .inner()
244 .map(|v| v.get_references(collection)),
245 EntityRef::Artifact(art) => art
246 .get_internal()
247 .inner()
248 .map(|v| v.get_references(collection)),
249 };
250 }
251}