Trait Entity

Source
pub trait Entity:
    Components
    + Send
    + 'static {
    type Ref<'cont>;
    type Mut<'cont>;

    const OFFSETS_BY_FIELD_INDEX: &'static [usize];

    // Required methods
    fn field_to_column_index(fi: usize) -> usize;
    fn get_ref_from<Cont: ContainEntity + ?Sized>(
        cont: &Cont,
        vi: usize,
    ) -> Self::Ref<'_>;
    fn get_mut_from<Cont: ContainEntity + ?Sized>(
        cont: &mut Cont,
        vi: usize,
    ) -> Self::Mut<'_>;

    // Provided methods
    fn column_to_field_index(ci: usize) -> usize { ... }
    fn num_components() -> usize { ... }
    fn component_ptr(&self, fi: usize) -> NonNull<u8> { ... }
    fn register_to<Cont: ContainEntity + ?Sized>(cont: &mut Cont) { ... }
    fn move_to<Cont: ContainEntity + ?Sized>(self, cont: &mut Cont) -> usize
       where Self: Sized { ... }
    fn take_from<Cont: ContainEntity + ?Sized>(
        cont: &mut Cont,
        vi: usize,
    ) -> Self
       where Self: Sized { ... }
}
Expand description

A set of components.

Implementing this trait is not mandatory, but by doing so, the crate can provide you more easy to use APIs. Plus, there is a derive macro that have the same name, which help you implement this trait. As a consequence, it’s encouraged to implement this trait by the derive macro about entity types that you know.

Required Associated Constants§

Source

const OFFSETS_BY_FIELD_INDEX: &'static [usize]

Offsets in bytes of each field.

See example below.

struct Entity {
    a: i32, // offset may be 0
    b: i8,  // offset may be 6
    c: i16, // offset may be 4
}

// Implementors must define offsets like this.
// OFFSETS_BY_FIELD_INDEX = &[0, 6, 4]
§Safety

Must be implemented correctly. Other methods depend on this offset with unsafe blocks.

Required Associated Types§

Source

type Ref<'cont>

Source

type Mut<'cont>

Required Methods§

Source

fn field_to_column_index(fi: usize) -> usize

Turns field index into column index.

This function could be called frequently, so that it’s recommended to cache the mapping from field index to column index in a way.

§Field index

Field index is an index assigned to a field in the order it is declared.

§Column index

Column index is a terminology used in ContainEntity. In short, it is an index sorted by ComponentKey.

§Safety

Must be implemented correctly. Other methods depend on this offset with unsafe blocks.

Source

fn get_ref_from<Cont: ContainEntity + ?Sized>( cont: &Cont, vi: usize, ) -> Self::Ref<'_>

Returns a struct holding shared references to components that belong to an entity for the given value index.

Note, however, that entity is not stored as it is. It is split up into its components then stored in each component container. That means collecting those references like this function is inefficient because it requires random access to memory.

derive(Entity) macro gives us a similar struct to Self. You can access each field via dot operator. Plus, it implements Debug, so that you can see how the entity looks like. But it will show some components only that implement Debug. See examples below.

§Panics

Panics if the given value index is out of bounds.

§Examples
use my_ecs::prelude::*;
use std::hash::RandomState;

#[derive(Entity, Debug, PartialEq)]
struct Ea {
    ca: Ca,
    cb: Cb,
}
#[derive(Component, Debug, PartialEq)]
struct Ca(i32);
#[derive(Component, Debug, PartialEq)]
struct Cb(String);

let mut cont: SparseSet<RandomState> = SparseSet::new();
Ea::register_to(&mut cont);
Ea { ca: Ca(42), cb: Cb("cb".to_owned()) }.move_to(&mut cont);

let e = Ea::get_ref_from(&cont, 0);
println!("{e:?}");
assert_eq!(e.ca, &Ca(42));
assert_eq!(e.cb, &Cb("cb".to_owned()));
Source

fn get_mut_from<Cont: ContainEntity + ?Sized>( cont: &mut Cont, vi: usize, ) -> Self::Mut<'_>

Returns a struct holding mutable references to components that belong to an entity for the given value index.

Note, however, that entity is not stored as it is. It is split up into its components then stored in each component container. That means collecting those references like this function is inefficient because it requires random access to memory.

derive(Entity) macro gives us a similar struct to Self. You can access each field via dot operator. Plus, it implements Debug, so that you can see how the entity looks like. But it will show some components only that implement Debug. See examples below.

§Panics

Panics if the given value index is out of bounds.

§Examples
use my_ecs::prelude::*;
use std::hash::RandomState;

#[derive(Entity, Debug, PartialEq)]
struct Ea {
    ca: Ca,
    cb: Cb,
}
#[derive(Component, Debug, PartialEq)]
struct Ca(i32);
#[derive(Component, Debug, PartialEq)]
struct Cb(String);

let mut cont: SparseSet<RandomState> = SparseSet::new();
Ea::register_to(&mut cont);
Ea { ca: Ca(1), cb: Cb("2".to_owned()) }.move_to(&mut cont);

let e = Ea::get_mut_from(&mut cont, 0);
println!("{e:?}");
assert_eq!(e.ca, &Ca(1));
assert_eq!(e.cb, &Cb("2".to_owned()));

*e.ca = Ca(3);
*e.cb = Cb("4".to_owned());

let e = Ea::get_ref_from(&cont, 0);
assert_eq!(e.ca, &Ca(3));
assert_eq!(e.cb, &Cb("4".to_owned()));

Provided Methods§

Source

fn column_to_field_index(ci: usize) -> usize

Turns column index into field index.

This function would be called infrequently, so that simple implementations would be good enough.

Source

fn num_components() -> usize

Returns number of components.

Source

fn component_ptr(&self, fi: usize) -> NonNull<u8>

Returns a pointer to a component in this entity for the given field index.

§Panics

Panics if the given index is out of bounds.

Source

fn register_to<Cont: ContainEntity + ?Sized>(cont: &mut Cont)

Registers components in this entity to an entity container.

§Panics

Panics if the given entity container has registered columns in it.

Source

fn move_to<Cont: ContainEntity + ?Sized>(self, cont: &mut Cont) -> usize
where Self: Sized,

Moves the entity to an entity container then returns row index to the moved entity.

§How to move

Use AddEntity::begin_add_row, AddEntity::add_value, and AddEntity::end_add_row, then forget self.

§Examples
use my_ecs::prelude::*;
use std::hash::RandomState;

#[derive(Entity, Debug, PartialEq)]
struct Ea {
    ca: Ca,
    cb: Cb,
}
#[derive(Component, Debug, PartialEq)]
struct Ca(i32);
#[derive(Component, Debug, PartialEq)]
struct Cb(String);

let mut cont: SparseSet<RandomState> = SparseSet::new();
Ea::register_to(&mut cont);
Ea { ca: Ca(42), cb: Cb("cb".to_owned()) }.move_to(&mut cont);
assert_eq!(cont.len(), 1);
Source

fn take_from<Cont: ContainEntity + ?Sized>(cont: &mut Cont, vi: usize) -> Self
where Self: Sized,

Removes an entity for the given value index from an entity container then returns the entity.

See ContainEntity document when you need to know what value index is.

§Panics

Panics if the given value index is out of bounds.

§Examples
use my_ecs::prelude::*;
use std::hash::RandomState;

#[derive(Entity, Debug, PartialEq)]
struct Ea {
    ca: Ca,
    cb: Cb,
}
#[derive(Component, Debug, PartialEq)]
struct Ca(i32);
#[derive(Component, Debug, PartialEq)]
struct Cb(String);

let mut cont: SparseSet<RandomState> = SparseSet::new();
Ea::register_to(&mut cont);
Ea { ca: Ca(42), cb: Cb("cb".to_owned()) }.move_to(&mut cont);
let e = Ea::take_from(&mut cont, 0);
assert_eq!(e, Ea { ca: Ca(42), cb: Cb("cb".to_owned()) });

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§