classicube_helpers\entities/
mod.rs1mod entity;
2use std::{
3 cell::RefCell,
4 collections::HashMap,
5 rc::{Rc, Weak},
6};
7
8use classicube_sys::{Entities, ENTITIES_MAX_COUNT};
9use tracing::warn;
10
11pub use self::entity::{Entity, ENTITY_SELF_ID};
12use crate::{
13 callback_handler::CallbackHandler,
14 events::entity::{AddedEvent, AddedEventHandler, RemovedEvent, RemovedEventHandler},
15};
16
17pub struct Entities {
19 entities: Rc<RefCell<HashMap<u8, Rc<Entity>>>>,
20
21 #[allow(clippy::type_complexity)]
22 added_callbacks: Rc<RefCell<CallbackHandler<(u8, Weak<Entity>)>>>,
23 #[allow(dead_code)]
24 added_handler: AddedEventHandler,
25
26 removed_callbacks: Rc<RefCell<CallbackHandler<u8>>>,
27 #[allow(dead_code)]
28 removed_handler: RemovedEventHandler,
29}
30
31impl Entities {
32 #[must_use]
34 pub fn new() -> Self {
35 let mut entities = HashMap::with_capacity(256);
36
37 unsafe {
39 entities.insert(
40 ENTITY_SELF_ID,
41 Rc::new(Entity::from_id(ENTITY_SELF_ID).expect("Entity::from_id(ENTITY_SELF_ID)")),
42 );
43 }
44
45 let entities = Rc::new(RefCell::new(entities));
46
47 let added_callbacks = Rc::new(RefCell::new(CallbackHandler::new()));
48 let mut added_handler = AddedEventHandler::new();
49 {
50 let entities = entities.clone();
51 let added_callbacks = added_callbacks.clone();
52 added_handler.on(move |AddedEvent { id }| {
53 let id = *id;
54 let entity = Rc::new(match unsafe { Entity::from_id(id) } {
55 None => {
56 warn!(?id, "AddedEvent Entity::from_id returned None");
57 return;
58 }
59 Some(entity) => entity,
60 });
61 let weak = Rc::downgrade(&entity);
62
63 {
64 let mut entities = entities.borrow_mut();
65 entities.insert(id, entity);
66 }
67
68 let mut added_callbacks = added_callbacks.borrow_mut();
69 added_callbacks.handle_event(&(id, weak));
70 });
71 }
72
73 let removed_callbacks = Rc::new(RefCell::new(CallbackHandler::new()));
74 let mut removed_handler = RemovedEventHandler::new();
75 {
76 let entities = entities.clone();
77 let removed_callbacks = removed_callbacks.clone();
78 removed_handler.on(move |RemovedEvent { id }| {
79 {
80 let mut entities = entities.borrow_mut();
81 entities.remove(id);
82 }
83
84 let mut removed_callbacks = removed_callbacks.borrow_mut();
85 removed_callbacks.handle_event(id);
86 });
87 }
88
89 let mut s = Self {
90 entities,
91 added_callbacks,
92 added_handler,
93 removed_callbacks,
94 removed_handler,
95 };
96
97 s.update_to_real_entities();
98
99 s
100 }
101
102 fn update_to_real_entities(&mut self) {
103 let mut entities = self.entities.borrow_mut();
104 entities.clear();
105
106 for id in 0..ENTITIES_MAX_COUNT {
107 unsafe {
108 if !Entities.List[id as usize].is_null() {
109 if let Some(entity) = Entity::from_id(u8::try_from(id).unwrap()) {
110 entities.insert(u8::try_from(id).unwrap(), Rc::new(entity));
111 }
112 }
113 }
114 }
115 }
116
117 pub fn on_added<F>(&mut self, callback: F)
118 where
119 F: FnMut(&(u8, Weak<Entity>)),
120 F: 'static,
121 {
122 let mut added_callbacks = self.added_callbacks.borrow_mut();
123 added_callbacks.on(callback);
124 }
125
126 pub fn on_removed<F>(&mut self, callback: F)
127 where
128 F: FnMut(&u8),
129 F: 'static,
130 {
131 let mut removed_callbacks = self.removed_callbacks.borrow_mut();
132 removed_callbacks.on(callback);
133 }
134
135 #[must_use]
136 pub fn get(&self, id: u8) -> Option<Weak<Entity>> {
137 let entities = self.entities.borrow();
138 let entity = entities.get(&id)?;
139 Some(Rc::downgrade(entity))
140 }
141
142 #[must_use]
143 pub fn get_all(&self) -> Vec<(u8, Weak<Entity>)> {
144 let entities = self.entities.borrow();
145 entities
146 .values()
147 .map(|entity| (entity.get_id(), Rc::downgrade(entity)))
148 .collect::<Vec<_>>()
149 }
150}
151
152impl Default for Entities {
153 fn default() -> Self {
154 Self::new()
155 }
156}