cellular_raza-concepts 0.5.0

cellular_raza concepts
Documentation
use cellular_raza_concepts::{CalcError, InteractionInformation};

#[test]
fn derive_cycle() {
    use cellular_raza_concepts::*;
    use cellular_raza_concepts_derive::CellAgent;
    use rand::SeedableRng;
    use rand_chacha::ChaCha8Rng;
    struct Agent;
    impl<NA> cellular_raza_concepts::Cycle<NA> for Agent {
        fn update_cycle(_rng: &mut ChaCha8Rng, _dt: &f64, _cell: &mut NA) -> Option<CycleEvent> {
            None
        }

        fn divide(_rng: &mut ChaCha8Rng, _cell: &mut NA) -> Result<NA, DivisionError> {
            unimplemented!()
        }
    }
    #[derive(CellAgent)]
    struct NewAgent1 {
        #[Cycle]
        _old_agent: Agent,
    }
    #[derive(CellAgent)]
    struct NewAgent2(#[Cycle] Agent);

    let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(1);
    let mut new_agent1 = NewAgent1 { _old_agent: Agent };
    let mut new_agent2 = NewAgent2(Agent);
    assert!(<NewAgent1 as Cycle>::update_cycle(&mut rng, &0.1, &mut new_agent1).is_none());
    assert!(<NewAgent2 as Cycle>::update_cycle(&mut rng, &0.1, &mut new_agent2).is_none());
}

#[test]
fn derive_position() {
    use cellular_raza_concepts::Position;
    use cellular_raza_concepts_derive::CellAgent;
    struct PositionModel;
    impl Position<u8> for PositionModel {
        fn pos(&self) -> u8 {
            1
        }

        fn set_pos(&mut self, _pos: &u8) {}
    }
    #[derive(CellAgent)]
    struct NewAgent {
        #[Position]
        pos_model: PositionModel,
    }
    let new_agent = NewAgent {
        pos_model: PositionModel,
    };
    assert_eq!(new_agent.pos(), 1);
}

#[test]
fn derive_velocity() {
    use cellular_raza_concepts::Velocity;
    use cellular_raza_concepts_derive::CellAgent;
    struct VelocityModel;
    impl Velocity<i32> for VelocityModel {
        fn velocity(&self) -> i32 {
            1
        }

        fn set_velocity(&mut self, _velocity: &i32) {}
    }
    #[derive(CellAgent)]
    struct NewAgent {
        #[Velocity]
        velocity_model: VelocityModel,
    }
    let new_agent = NewAgent {
        velocity_model: VelocityModel,
    };
    assert_eq!(new_agent.velocity(), 1);
}

#[test]
fn derive_mechanics() {
    use cellular_raza_concepts::*;
    use cellular_raza_concepts_derive::CellAgent;
    struct MechanicsModel;
    impl cellular_raza_concepts::Mechanics<f32, f32, f32, f32> for MechanicsModel {
        fn calculate_increment(&self, force: f32) -> Result<(f32, f32), CalcError> {
            Ok((0.0, force))
        }

        fn get_random_contribution(
            &self,
            _rng: &mut rand_chacha::ChaCha8Rng,
            _dt: f32,
        ) -> Result<(f32, f32), RngError> {
            unimplemented!()
        }
    }
    #[derive(CellAgent)]
    struct NewAgent1 {
        #[Mechanics]
        mechanics: MechanicsModel,
    }

    let new_agent = NewAgent1 {
        mechanics: MechanicsModel,
    };
    let (dx, dv) = new_agent.calculate_increment(0.1).unwrap();
    assert_eq!(dx, 0.0);
    assert_eq!(dv, 0.1);
}

#[test]
fn derive_interaction() {
    use cellular_raza_concepts::*;
    use cellular_raza_concepts_derive::CellAgent;
    struct InteractionModel;
    impl cellular_raza_concepts::Interaction<f32, f32, f32, ()> for InteractionModel {
        fn calculate_force_between(
            &self,
            _own_pos: &f32,
            _ext_pos: &f32,
            _own_vel: &f32,
            _ext_vel: &f32,
            _ext_info: &(),
        ) -> Result<(f32, f32), CalcError> {
            unimplemented!()
        }
    }
    impl cellular_raza_concepts::InteractionInformation<()> for InteractionModel {
        fn get_interaction_information(&self) {}
    }
    #[derive(CellAgent)]
    struct NewAgent1 {
        #[Interaction]
        interaction: InteractionModel,
    }

    let newagent = NewAgent1 {
        interaction: InteractionModel,
    };
    assert_eq!(newagent.get_interaction_information(), ());
}

#[test]
fn derive_interaction_generics() {
    use cellular_raza_concepts::Interaction;
    use cellular_raza_concepts_derive::CellAgent;

    struct InteractionModel<const D: usize> {
        index: [usize; D],
    }

    impl<const D: usize> Interaction<f32, f32, f32, [usize; D]> for InteractionModel<D> {
        fn calculate_force_between(
            &self,
            _own_pos: &f32,
            _own_vel: &f32,
            _ext_pos: &f32,
            _ext_vel: &f32,
            _ext_info: &[usize; D],
        ) -> Result<(f32, f32), cellular_raza_concepts::CalcError> {
            Ok((0.0, 0.0))
        }
    }

    impl<const D: usize> InteractionInformation<[usize; D]> for InteractionModel<D> {
        fn get_interaction_information(&self) -> [usize; D] {
            self.index
        }
    }

    #[derive(CellAgent)]
    struct NewAgent<const D: usize> {
        #[Interaction]
        interaction: InteractionModel<D>,
    }

    let my_agent = NewAgent {
        interaction: InteractionModel { index: [1, 2, 3] },
    };
    assert_eq!(my_agent.get_interaction_information(), [1, 2, 3]);
}

#[test]
fn derive_neighbor_interaction() {
    use cellular_raza_concepts::NeighborSensing;
    use cellular_raza_concepts_derive::CellAgent;

    struct Senser;

    impl InteractionInformation<i8> for Senser {
        fn get_interaction_information(&self) -> i8 {
            0
        }
    }

    impl NeighborSensing<f32, usize, i8> for Senser {
        fn accumulate_information(
            &self,
            _: &f32,
            _: &f32,
            ext_inf: &i8,
            accumulator: &mut usize,
        ) -> Result<(), CalcError> {
            *accumulator += *ext_inf as usize;
            Ok(())
        }

        fn react_to_neighbors(&mut self, _: &usize) -> Result<(), CalcError> {
            Ok(())
        }

        fn clear_accumulator(accumulator: &mut usize) {
            *accumulator = 0;
        }
    }

    #[derive(CellAgent)]
    struct Agent {
        #[NeighborSensing]
        senser: Senser,
    }

    let senser = Senser;

    let mut accumulator = 0;
    for i in 0..10 {
        senser
            .accumulate_information(&0., &0., &i, &mut accumulator)
            .unwrap();
    }

    let mut cell = Agent { senser };
    cell.react_to_neighbors(&accumulator).unwrap();
    cell.get_interaction_information();
}