steel_core/entity/base/
relationships.rs1use std::sync::Weak;
2
3use crate::entity::{RemovalReason, SharedEntity, WeakEntity};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub(super) struct EntityLifecycleState {
8 pub(super) removal_reason: Option<RemovalReason>,
9 pub(super) pending_world_change: Option<PendingWorldChangeToken>,
10 pub(super) next_world_change_token: u64,
11}
12
13impl EntityLifecycleState {
14 pub(super) const fn new() -> Self {
15 Self {
16 removal_reason: None,
17 pending_world_change: None,
18 next_world_change_token: 1,
19 }
20 }
21
22 pub(super) fn next_world_change_token(&mut self) -> PendingWorldChangeToken {
23 let token = PendingWorldChangeToken(self.next_world_change_token);
24 self.next_world_change_token = self.next_world_change_token.wrapping_add(1).max(1);
25 token
26 }
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34pub struct PendingWorldChangeToken(u64);
35
36impl PendingWorldChangeToken {
37 #[cfg(test)]
38 pub(crate) const fn for_test(value: u64) -> Self {
39 Self(value)
40 }
41}
42
43#[derive(Default)]
49pub(super) struct EntityRelationshipState {
50 pub(super) vehicle: Option<WeakEntity>,
51 pub(super) passengers: Vec<WeakEntity>,
52 pub(super) boarding_cooldown: i32,
53}
54
55impl EntityRelationshipState {
56 pub(super) fn vehicle(&mut self) -> Option<SharedEntity> {
57 let vehicle = self.vehicle.as_ref().and_then(Weak::upgrade);
58 if vehicle.is_none() {
59 self.vehicle = None;
60 }
61 vehicle
62 }
63
64 pub(super) fn passengers(&mut self) -> Vec<SharedEntity> {
65 let mut live_passengers = Vec::new();
66 self.passengers.retain(|passenger| {
67 if let Some(entity) = passenger.upgrade() {
68 live_passengers.push(entity);
69 true
70 } else {
71 false
72 }
73 });
74 live_passengers
75 }
76
77 pub(super) fn first_passenger(&mut self) -> Option<SharedEntity> {
78 self.passengers
79 .retain(|passenger| passenger.strong_count() > 0);
80 self.passengers.first().and_then(Weak::upgrade)
81 }
82
83 pub(super) fn has_passenger_id(&mut self, passenger_id: i32) -> bool {
84 self.passengers
85 .retain(|passenger| passenger.strong_count() > 0);
86 self.passengers.iter().any(|passenger| {
87 passenger
88 .upgrade()
89 .is_some_and(|entity| entity.id() == passenger_id)
90 })
91 }
92
93 pub(super) fn remove_passenger_id(&mut self, passenger_id: i32) -> bool {
94 let mut removed = false;
95 self.passengers.retain(|passenger| {
96 let Some(entity) = passenger.upgrade() else {
97 return false;
98 };
99 if entity.id() == passenger_id {
100 removed = true;
101 false
102 } else {
103 true
104 }
105 });
106 removed
107 }
108}