Moved in sparse set tests
This commit is contained in:
		
							parent
							
								
									f93fb22699
								
							
						
					
					
						commit
						a49d3e6888
					
				
							
								
								
									
										17
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,16 +1 @@ | |||||||
| # ---> Rust | /target | ||||||
| # Generated by Cargo |  | ||||||
| # will have compiled files and executables |  | ||||||
| debug/ |  | ||||||
| target/ |  | ||||||
| 
 |  | ||||||
| # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries |  | ||||||
| # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html |  | ||||||
| Cargo.lock |  | ||||||
| 
 |  | ||||||
| # These are backup files generated by rustfmt |  | ||||||
| **/*.rs.bk |  | ||||||
| 
 |  | ||||||
| # MSVC Windows builds of rustc generate these, which store debugging information |  | ||||||
| *.pdb |  | ||||||
| 
 |  | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | # This file is automatically @generated by Cargo. | ||||||
|  | # It is not intended for manual editing. | ||||||
|  | version = 3 | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ecs" | ||||||
|  | version = "0.1.0" | ||||||
							
								
								
									
										8
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | [package] | ||||||
|  | name = "ecs" | ||||||
|  | version = "0.1.0" | ||||||
|  | edition = "2021" | ||||||
|  | 
 | ||||||
|  | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
							
								
								
									
										91
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,91 @@ | |||||||
|  | use std::fmt; | ||||||
|  | 
 | ||||||
|  | // Error type
 | ||||||
|  | struct SparseSetError; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Copy, Clone)] | ||||||
|  | struct DenseItem<T> { | ||||||
|  |     index: usize, | ||||||
|  |     value: T | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // TODO: Use arrays+slices instead of vecs
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct SparseSet<T> { | ||||||
|  |     sparse: Vec<Option<usize>>, | ||||||
|  |     dense: Vec<DenseItem<T>> | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<T> SparseSet<T> { | ||||||
|  |     pub fn new() -> SparseSet<T> { | ||||||
|  |         SparseSet { | ||||||
|  |             sparse: vec![], | ||||||
|  |             dense: vec![] | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Add an item to the dense vector and record its index in the sparse vector
 | ||||||
|  |     fn insert(&mut self, value: T) { | ||||||
|  |         let item = DenseItem { | ||||||
|  |             index: self.dense.len(), | ||||||
|  |             value: value | ||||||
|  |         }; | ||||||
|  |         self.dense.push(item); | ||||||
|  |         let dense_index = self.dense.len() - 1; | ||||||
|  |         self.sparse.push(Some(dense_index)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Remove an item at the supplied target index from the set
 | ||||||
|  |     // Replaces the selected target with the last item in the dense vector
 | ||||||
|  |     fn remove(&mut self, target_sparse_index: usize) -> Result<(), SparseSetError> { | ||||||
|  |         // Find the dense index of the target (need to decide what to do from there)
 | ||||||
|  |         let target_dense_index = self.sparse[target_sparse_index].unwrap(); | ||||||
|  | 
 | ||||||
|  |         // If the target points to the last item in the dense set, this'll be easier
 | ||||||
|  |         if target_dense_index + 1 == self.dense.len() { | ||||||
|  |             // Remove the target from the dense set
 | ||||||
|  |             self.dense.pop(); | ||||||
|  | 
 | ||||||
|  |             // Overwrite the target's sparse index
 | ||||||
|  |             self.sparse[target_sparse_index] = None; | ||||||
|  |         } else { | ||||||
|  |             // Get the last item in the dense set as a source to switch with
 | ||||||
|  |             // Change its index to the target sparse index, as it's replacing the target
 | ||||||
|  |             let source_item = match self.dense.pop() { | ||||||
|  |                 Some(item) => { item }, | ||||||
|  |                 None => { return Err(SparseSetError) } | ||||||
|  |             }; | ||||||
|  |     
 | ||||||
|  |             // Redirect the source item's sparse index to replace the target sparse index
 | ||||||
|  |             self.sparse[source_item.index] = Some(target_sparse_index); | ||||||
|  |     
 | ||||||
|  |             // Assign the source item to the target's place in the dense set
 | ||||||
|  |             self.dense[target_dense_index] = source_item; | ||||||
|  |     
 | ||||||
|  |             // Overwrite the target's sparse index
 | ||||||
|  |             self.sparse[target_dense_index] = None; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  |     let mut test_set: SparseSet<f32> = SparseSet::new(); | ||||||
|  |     test_set.insert(69.0); | ||||||
|  |     test_set.insert(420.0); | ||||||
|  |     test_set.insert(9001.0); | ||||||
|  |     println!("{:?}", test_set); | ||||||
|  |     test_set.remove(1); | ||||||
|  |     println!("{:?}", test_set); | ||||||
|  | 
 | ||||||
|  |     // Create a mutable array (contiguous memory!)
 | ||||||
|  |     let mut array: [Option<DenseItem<f32>>; 8] = [None; 8]; | ||||||
|  | 
 | ||||||
|  |     // Create a mutable slice of that whole array
 | ||||||
|  |     let slice: &[Option<DenseItem<f32>>] = &mut array[..]; | ||||||
|  | 
 | ||||||
|  |     for item in slice { | ||||||
|  |         println!("{:?}", item); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user