swamp_script_core_extra/
extra.rs1use crate::idx_gen::IndexAllocator;
7use crate::qck_des::quick_deserialize;
8use crate::value::{QuickDeserialize, Value, to_rust_value};
9use crate::value::{QuickSerialize, ValueRef};
10use sparse_slot::{Id, SparseSlot};
11use std::cell::RefCell;
12use std::fmt::{Debug, Display, Formatter};
13use std::rc::Rc;
14use swamp_script_types::ExternalType;
15use swamp_script_types::Type;
16
17#[derive(Debug, PartialEq, Eq)]
18pub struct SparseValueId(pub Id);
19
20impl Display for SparseValueId {
21 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
22 write!(f, "id:{}:{}", self.0.index, self.0.generation)
23 }
24}
25
26impl QuickDeserialize for SparseValueId {
27 fn quick_deserialize(octets: &[u8]) -> (Self, usize) {
28 let mut offset = 0;
29
30 let index = u16::from_le_bytes(octets[offset..offset + 2].try_into().unwrap());
32 offset += 2;
33
34 let generation = u8::from_le_bytes(octets[offset..offset + 1].try_into().unwrap());
36 offset += 1;
37
38 let id = Id::new(index.into(), generation);
39
40 (SparseValueId(id), offset)
41 }
42}
43
44impl QuickSerialize for SparseValueId {
45 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
46 let mut offset = 0;
47
48 let index_octets = (self.0.index as u16).to_le_bytes();
50 octets[offset..offset + index_octets.len()].copy_from_slice(&index_octets);
51 offset += index_octets.len();
52
53 let generation_octets = self.0.generation.to_le_bytes();
55 octets[offset..offset + generation_octets.len()].copy_from_slice(&generation_octets);
56 offset += generation_octets.len();
57
58 offset
59 }
60}
61
62#[derive()]
63pub struct SparseValueMap {
64 pub sparse_slot: SparseSlot<Rc<RefCell<Value>>>,
65 pub id_generator: IndexAllocator,
66 pub value_item_type: Type,
67 pub rust_type_ref_for_id: ExternalType,
68}
69
70impl Debug for SparseValueMap {
71 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72 writeln!(f, "SparseValueMap")?;
73
74 for (id, val) in self.sparse_slot.iter() {
75 writeln!(f, " {id}: {}", val.borrow())?;
76 }
77
78 Ok(())
79 }
80}
81
82impl QuickSerialize for SparseValueMap {
83 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
84 let mut offset = 0;
85
86 let count = self.sparse_slot.len() as u16;
87 let count_octets = count.to_le_bytes();
88 octets[offset..offset + count_octets.len()].copy_from_slice(&count_octets);
89 offset += count_octets.len();
90
91 for (id, value) in self.sparse_slot.iter() {
92 let short_index = id.index as u16;
93 let key_index_octets = short_index.to_le_bytes();
94 octets[offset..offset + key_index_octets.len()].copy_from_slice(&key_index_octets);
95 offset += key_index_octets.len();
96
97 let key_generation_octets = id.generation.to_le_bytes();
98 octets[offset..offset + key_generation_octets.len()]
99 .copy_from_slice(&key_generation_octets);
100 offset += key_generation_octets.len();
101
102 let value_size = value.borrow().quick_serialize(&mut octets[offset..], 0);
103 offset += value_size;
104 }
105
106 offset
107 }
108}
109
110impl SparseValueMap {
111 #[must_use]
114 pub fn quick_deserialize(
115 key_type: ExternalType,
116 value_item_type: Type,
117 octets: &[u8],
118 ) -> (Self, usize) {
119 let mut sparse = Self::new(key_type, value_item_type.clone());
120 let mut offset = 0;
121 let count = u16::from_le_bytes(
122 octets[offset..offset + 2]
123 .try_into()
124 .expect("could not convert to u16 count"),
125 );
126 offset += 2;
127
128 for _i in 0..count {
129 let index = u16::from_le_bytes(
130 octets[offset..offset + 2]
131 .try_into()
132 .expect("could not convert to u16 index"),
133 );
134 offset += 2;
135
136 let generation = u8::from_le_bytes(
137 octets[offset..offset + 1]
138 .try_into()
139 .expect("could not convert to u16 generation"),
140 );
141 offset += 1;
142
143 let (value, octet_size) =
144 quick_deserialize(&value_item_type.clone(), &octets[offset..], 0);
145 offset += octet_size;
146
147 let id = Id::new(index as usize, generation);
148 let deserialized_value_ref = Rc::new(RefCell::new(value));
149 sparse
150 .sparse_slot
151 .try_set(id, deserialized_value_ref)
152 .expect("could not insert into SparseValueMap");
153
154 sparse
155 .id_generator
156 .reserve(index as usize, generation.into());
157 }
158
159 (sparse, offset)
160 }
161}
162
163impl Display for SparseValueMap {
164 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165 write!(
166 f,
167 "Sparse<{:?}> len:{}",
168 self.value_item_type,
169 self.sparse_slot.len()
170 )
171 }
172}
173
174impl SparseValueMap {
175 #[must_use]
176 pub fn new(rust_type_ref_for_id: ExternalType, value_item_type: Type) -> Self {
177 Self {
183 sparse_slot: SparseSlot::<Rc<RefCell<Value>>>::new(2048),
184 id_generator: IndexAllocator::new(),
185 value_item_type,
186 rust_type_ref_for_id,
187 }
188 }
189
190 pub fn add(&mut self, v: Value) -> Value {
193 let (index, generation) = self.id_generator.create();
195
196 let id = Id { index, generation };
197
198 let mutable_reference = Rc::new(RefCell::new(v));
200
201 self.sparse_slot
202 .try_set(id, mutable_reference)
203 .expect("sparse should work");
204
205 let script_id = SparseValueId(id);
206
207 to_rust_value(self.rust_type_ref_for_id.clone(), script_id)
208 }
209
210 pub fn remove(&mut self, id: &SparseValueId) {
211 self.id_generator.remove((id.0.index, id.0.generation));
212 self.sparse_slot.remove(id.0);
213 }
214
215 #[must_use]
216 pub fn get(&self, id: &SparseValueId) -> Option<&ValueRef> {
217 self.sparse_slot.get(id.0)
218 }
219
220 #[allow(unused)]
221 #[must_use]
222 pub fn iter(&self) -> sparse_slot::Iter<'_, Rc<RefCell<Value>>> {
223 self.sparse_slot.iter()
224 }
225
226 pub fn iter_mut(&mut self) -> sparse_slot::IterMut<'_, Rc<RefCell<Value>>> {
227 self.sparse_slot.iter_mut()
228 }
229
230 #[must_use]
231 pub fn values(&self) -> Vec<Rc<RefCell<Value>>> {
232 self.sparse_slot.iter().map(|(_id, v)| v.clone()).collect()
233 }
234}