|
@@ -117,6 +117,7 @@ pub struct EntityState {
|
|
typeid: std::any::TypeId,
|
|
typeid: std::any::TypeId,
|
|
|
|
|
|
pub parts: Vec<PartState>,
|
|
pub parts: Vec<PartState>,
|
|
|
|
+ pub has_idmap: bool,
|
|
}
|
|
}
|
|
|
|
|
|
impl EntityState {
|
|
impl EntityState {
|
|
@@ -153,6 +154,7 @@ impl EntityState {
|
|
name: E::entity_name(),
|
|
name: E::entity_name(),
|
|
typeid: std::any::TypeId::of::<E>(),
|
|
typeid: std::any::TypeId::of::<E>(),
|
|
parts: pv.0,
|
|
parts: pv.0,
|
|
|
|
+ has_idmap: false,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -166,21 +168,34 @@ impl EntityStateContainer {
|
|
pub fn iter_states(&self) -> impl Iterator<Item = &EntityState> {
|
|
pub fn iter_states(&self) -> impl Iterator<Item = &EntityState> {
|
|
self.states.values()
|
|
self.states.values()
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-impl EntityVisitor for EntityStateContainer {
|
|
|
|
- fn visit<E: Entity>(&mut self) {
|
|
|
|
|
|
+ pub fn visit_idmap<E: Entity>(&mut self) {
|
|
|
|
+ self.handle_visit::<E>(true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fn handle_visit<E: Entity>(&mut self, is_idmap: bool) {
|
|
|
|
+ let entry = self.states.entry(E::entity_name());
|
|
// cases:
|
|
// cases:
|
|
// 1. we haven't seen this entity
|
|
// 1. we haven't seen this entity
|
|
// 2. we've seen this entity before
|
|
// 2. we've seen this entity before
|
|
-
|
|
|
|
- if self.states.contains_key(E::entity_name()) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- let entry = self.states.entry(E::entity_name());
|
|
|
|
|
|
+ // 2a. this entity has no idmap yet
|
|
|
|
+ // 2b. this entity has an idmap already
|
|
|
|
+
|
|
|
|
+ use std::collections::hash_map::Entry;
|
|
|
|
+ match entry {
|
|
|
|
+ Entry::Occupied(mut entry) => {
|
|
|
|
+ if entry.get().has_idmap && is_idmap {
|
|
|
|
+ panic!("duplicate IDMap for entity {}", E::entity_name())
|
|
|
|
+ } else if is_idmap {
|
|
|
|
+ entry.get_mut().has_idmap = true;
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ },
|
|
|
|
+ _ => (),
|
|
|
|
+ };
|
|
|
|
|
|
let entry = entry.or_insert_with(EntityState::build::<E>);
|
|
let entry = entry.or_insert_with(EntityState::build::<E>);
|
|
|
|
+ entry.has_idmap = is_idmap;
|
|
// sanity-check
|
|
// sanity-check
|
|
if entry.typeid != std::any::TypeId::of::<E>() {
|
|
if entry.typeid != std::any::TypeId::of::<E>() {
|
|
panic!("Identical entity name but different typeid!");
|
|
panic!("Identical entity name but different typeid!");
|
|
@@ -200,3 +215,9 @@ impl EntityVisitor for EntityStateContainer {
|
|
E::accept_part_visitor(&mut RecursiveVisitor(self, Default::default()));
|
|
E::accept_part_visitor(&mut RecursiveVisitor(self, Default::default()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+impl EntityVisitor for EntityStateContainer {
|
|
|
|
+ fn visit<E: Entity>(&mut self) {
|
|
|
|
+ self.handle_visit::<E>(false);
|
|
|
|
+ }
|
|
|
|
+}
|