Moved in sparse set tests
This commit is contained in:
		
							parent
							
								
									f93fb22699
								
							
						
					
					
						commit
						a49d3e6888
					
				
							
								
								
									
										17
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,16 +1 @@ | ||||
| # ---> Rust | ||||
| # 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 | ||||
| 
 | ||||
| /target | ||||
|  | ||||
							
								
								
									
										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