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§
Sourceconst OFFSETS_BY_FIELD_INDEX: &'static [usize]
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§
Required Methods§
Sourcefn field_to_column_index(fi: usize) -> usize
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.
Sourcefn get_ref_from<Cont: ContainEntity + ?Sized>(
cont: &Cont,
vi: usize,
) -> Self::Ref<'_>
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()));Sourcefn get_mut_from<Cont: ContainEntity + ?Sized>(
cont: &mut Cont,
vi: usize,
) -> Self::Mut<'_>
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§
Sourcefn column_to_field_index(ci: usize) -> usize
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.
Sourcefn num_components() -> usize
fn num_components() -> usize
Returns number of components.
Sourcefn component_ptr(&self, fi: usize) -> NonNull<u8>
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.
Sourcefn register_to<Cont: ContainEntity + ?Sized>(cont: &mut Cont)
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.
Sourcefn move_to<Cont: ContainEntity + ?Sized>(self, cont: &mut Cont) -> usizewhere
Self: Sized,
fn move_to<Cont: ContainEntity + ?Sized>(self, cont: &mut Cont) -> usizewhere
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);Sourcefn take_from<Cont: ContainEntity + ?Sized>(cont: &mut Cont, vi: usize) -> Selfwhere
Self: Sized,
fn take_from<Cont: ContainEntity + ?Sized>(cont: &mut Cont, vi: usize) -> Selfwhere
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.