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…
Reference in New Issue
Block a user