ecs?
This commit is contained in:
		
					parent
					
						
							
								0eeb4b2563
							
						
					
				
			
			
				commit
				
					
						ca57bce787
					
				
			
		
					 7 changed files with 177 additions and 484 deletions
				
			
		
							
								
								
									
										131
									
								
								crates/moonhare_ecs/src/generational_index.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								crates/moonhare_ecs/src/generational_index.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,131 @@ | |||
| #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] | ||||
| pub struct GenerationalIndex { | ||||
|     index: usize, | ||||
|     generation: u64, | ||||
| } | ||||
| 
 | ||||
| impl GenerationalIndex { | ||||
|     pub fn index(&self) -> usize { | ||||
|         self.index | ||||
|     } | ||||
|     
 | ||||
|     pub fn generation(&self) -> u64 { | ||||
|         self.generation | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct AllocatorEntry { | ||||
|     is_live: bool, | ||||
|     generation: u64, | ||||
| } | ||||
| 
 | ||||
| pub struct GenerationalIndexAllocator { | ||||
|     entries: Vec<AllocatorEntry>, | ||||
|     free: Vec<usize>, | ||||
| } | ||||
| 
 | ||||
| impl GenerationalIndexAllocator { | ||||
|     pub fn allocate(&mut self) -> GenerationalIndex { | ||||
|         match self.free.pop() { | ||||
|             Some(index) =>{ | ||||
|                 self.entries[index].generation += 1; | ||||
|                 self.entries[index].is_live = true; | ||||
| 
 | ||||
|                 GenerationalIndex { | ||||
|                     index, | ||||
|                     generation: self.entries[index].generation, | ||||
|                 } | ||||
|             }, | ||||
|             None => { | ||||
|                 self.entries.push(AllocatorEntry { 
 | ||||
|                     is_live: true, 
 | ||||
|                     generation: 0, 
 | ||||
|                 }); | ||||
| 
 | ||||
|                 GenerationalIndex { | ||||
|                     index: self.entries.len() -1, | ||||
|                     generation: 0, | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Returns true if the index was allocated before and is now deallocated
 | ||||
|     pub fn deallocate(&mut self, index: GenerationalIndex) -> bool { | ||||
|         if self.is_live(index) { | ||||
|             self.entries[index.index()].is_live = false; | ||||
|             self.free.push(index.index()); | ||||
|             true | ||||
|         } else { | ||||
|             false | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn is_live(&self, index: GenerationalIndex) -> bool { | ||||
|         index.index() < self.entries.len() && self.entries[index.index()].generation == index.generation && self.entries[index.index()].is_live | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct ArrayEntry<T> { | ||||
|     value: T, | ||||
|     generation: u64, | ||||
| } | ||||
| 
 | ||||
| pub struct GenerationalIndexArray<T>(Vec<Option<ArrayEntry<T>>>); | ||||
| 
 | ||||
| impl <T> GenerationalIndexArray<T> { | ||||
|     pub fn set(&mut self, index: GenerationalIndex, value: T) { | ||||
|         while self.0.len() <= index.index()  { | ||||
|             self.0.push(None); | ||||
|         } | ||||
| 
 | ||||
|         let previous_generation = match &self.0[index.index()] { | ||||
|             Some(entry) => entry.generation, | ||||
|             None => 0, | ||||
|         }; | ||||
| 
 | ||||
|         if previous_generation > index.generation() { | ||||
|             panic!("write an index from previous gen"); | ||||
|         } | ||||
| 
 | ||||
|         self.0[index.index()] = Some(ArrayEntry { 
 | ||||
|             value, 
 | ||||
|             generation: index.generation(), 
 | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     pub fn remove(&mut self, index: GenerationalIndex) { | ||||
|         if index.index() < self.0.len() { | ||||
|             self.0[index.index()] = None; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get(&self, index: GenerationalIndex) -> Option<&T> { | ||||
|         if index.index() >= self.0.len() { | ||||
|             return None; | ||||
|         } | ||||
| 
 | ||||
|         match &self.0[index.index()] { | ||||
|             Some(entry) => if entry.generation == index.generation() { | ||||
|                 Some(&entry.value) | ||||
|             } else { | ||||
|                 None | ||||
|             }, | ||||
|             None => None | ||||
|         } | ||||
|     } | ||||
|     pub fn get_mut(&mut self, index: GenerationalIndex) -> Option<&mut T> { | ||||
|         if index.index() >= self.0.len() { | ||||
|             return None; | ||||
|         } | ||||
| 
 | ||||
|         match &mut self.0[index.index()] { | ||||
|             Some(entry) => if entry.generation == index.generation() { | ||||
|                 Some(&mut entry.value) | ||||
|             } else { | ||||
|                 None | ||||
|             }, | ||||
|             None => None | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue