tnaps 0.1.0

tnaps provides an entity-component-system framework in Rust.
Documentation
//! An example ECS system using tnaps.

use std::sync::Arc;

use tnaps::{
    system, system_parallel, ComponentChange, ComponentCollection, ComponentRef,
    CopyOnWriteComponentCollection, CopyOnWriteComponentRef, Entity as EntityTrait,
    MutableComponentCollection, MutableComponentRef, NopPartitioningScheme, Partitioned,
    PartitioningScheme, ThreadPool,
};

type Entity = u128;

struct MySystem1;

system! {
    MySystem1<Entity> {
        a: CopyOnWriteComponentCollection<u8>,
    }
}

impl MySystem1 {
    fn process(&self, entity: Entity, _: &mut CopyOnWriteComponentRef<u8>) {
        println!("processing: {}", entity);
    }
}

struct MySystem2;

system! {
    MySystem2<Entity> {
        a: CopyOnWriteComponentCollection<u8>,
        b: MutableComponentCollection<&'static str>,
    }
}

impl MySystem2 {
    fn process(
        &self,
        entity: Entity,
        _: &mut CopyOnWriteComponentRef<u8>,
        c2: &mut MutableComponentRef<&'static str>,
    ) {
        if entity == 2 {
            c2.unbind();
        }
        println!("processing: {}", entity);
    }
}

struct MySystem3;

system_parallel! {
    MySystem3<Entity> {
        a: CopyOnWriteComponentCollection<u8>,
        b: MutableComponentCollection<&'static str>,
        c: CopyOnWriteComponentCollection<f64>,
    }
}

impl MySystem3 {
    fn process(
        &self,
        entity: Entity,
        _: &mut CopyOnWriteComponentRef<u8>,
        _: &mut MutableComponentRef<&'static str>,
        c3: &mut CopyOnWriteComponentRef<f64>,
    ) {
        if entity == 3 {
            c3.update(|x| *x = 0.0);
        }
        println!("processing: {}", entity);
    }
}

fn main() {
    let mut collection1 = CopyOnWriteComponentCollection::from_iter(vec![
        (1u128, 42u8),
        (2u128, 69u8),
        (3u128, 99u8),
    ]);
    let mut collection2 = MutableComponentCollection::from_iter(vec![
        (1u128, "hello"),
        (2u128, "world"),
        (3u128, "!!!"),
    ]);
    let collection3 = CopyOnWriteComponentCollection::from_iter(vec![
        (1u128, std::f64::consts::PI),
        (2u128, std::f64::consts::E),
        (3u128, std::f64::consts::SQRT_2),
    ]);
    let sys1 = MySystem1;
    let sys2 = MySystem2;
    let sys3 = std::sync::Arc::new(MySystem3);
    println!("----");
    let (changes1,) = sys1.run(&mut collection1);
    assert!(changes1.is_empty());
    println!("----");
    let (changes1, changes2) = sys2.run(&mut collection1, &mut collection2);
    assert!(changes1.is_empty());
    collection2.apply(changes2);
    println!("collection2: {:?}", collection2);
    println!("----");
    let partitioning: Arc<dyn PartitioningScheme<Entity>> = Arc::new(NopPartitioningScheme);
    let collection1 = Partitioned::from(&partitioning, collection1.partition(&*partitioning));
    let mut collection2 = Partitioned::from(&partitioning, collection2.partition(&*partitioning));
    let mut collection3 = Partitioned::from(&partitioning, collection3.partition(&*partitioning));
    let thread_pool = ThreadPool::new("demo", 16);
    let (changes1, changes2, changes3) =
        sys3.run(&thread_pool, &collection1, &collection2, &collection3)();
    assert!(changes1.iter().all(|x| x.is_empty()));
    collection2.apply(changes2);
    collection3.apply(changes3);
    println!("collection2: {:?}", collection2);
    println!("collection3: {:?}", collection3);
}