Skip to content
This repository has been archived by the owner on Feb 18, 2021. It is now read-only.

Documentation #3

Merged
merged 4 commits into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;

/// A builder that simplifies the creation of a single entity.
#[derive(Default)]
pub struct EntityBuilder {
/// Raw component storage. Each component is written
Expand All @@ -27,6 +28,9 @@ impl EntityBuilder {
Self::default()
}

/// Adds a component to an entity, or sets its value if the component is present.
///
/// Returns `Self` such that method calls for `EntityBuilder`can be chained.
pub fn with<C>(mut self, component: C) -> Self
where
C: Component,
Expand All @@ -36,6 +40,7 @@ impl EntityBuilder {
self
}

/// Adds a component to an entity, or sets its value if the component is present.
pub fn add<C>(&mut self, component: C) -> &mut Self
where
C: Component,
Expand Down Expand Up @@ -75,7 +80,6 @@ impl EntityBuilder {
self.component_data.push((type_id, meta, self.cursor));

self.cursor += size;

self
}

Expand All @@ -87,13 +91,15 @@ impl EntityBuilder {
.write_unaligned(component);
}

/// Builds the components into an entity that can be inserted into a world.
pub fn build(self) -> BuiltEntity<'static> {
BuiltEntity {
builder: CowMut::Owned(self),
written: false,
}
}

/// Builds the components into an entity without deallocating the internals.
pub fn build_one(&mut self) -> BuiltEntity {
BuiltEntity {
builder: CowMut::Borrowed(self),
Expand Down Expand Up @@ -141,6 +147,7 @@ impl<'a> IntoComponentSource for BuiltEntity<'a> {
}

impl<'a> BuiltEntity<'a> {
/// Spawns the built entity into the given world.
pub fn spawn_in(self, world: &mut World) -> Entity {
world.spawn(self)[0]
}
Expand Down
14 changes: 14 additions & 0 deletions src/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,41 @@ use crate::{Entity, World};
use legion::borrow::Ref;
use legion::storage::Component;

/// A refrence to a `World` and `Entity` to allow for easy retrival of components.
pub struct EntityRef<'a> {
pub(crate) world: &'a World,
pub(crate) entity: Entity,
}

impl<'a> EntityRef<'a> {
/// Borrows component data `C` from the referenced world and entity.
///
/// Panics if the entity was not found or did not contain the specified component.
pub fn get<C>(&self) -> Ref<C>
where
C: Component,
{
self.try_get().unwrap()
}

/// Borrows component data `C` from the referenced world and entity.
///
/// Returns `Some(data)` if the entity was found and contains the specified data.
/// Otherwise `None` is returned.
pub fn try_get<C>(&self) -> Option<Ref<C>>
where
C: Component,
{
self.world.try_get(self.entity)
}

/// Returns the referenced entity.
pub fn entity(&self) -> Entity {
self.entity
}

/// Returns the referenced world.
pub fn world(&self) -> &'a World {
self.world
}
}
2 changes: 1 addition & 1 deletion src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl EventHandlers {
}
}

/// Triggers an event.
/// Emits the given event `E` with the given resources and world.
pub fn trigger<E>(&self, resources: &impl ResourcesProvider, world: &mut World, event: E)
where
E: Event,
Expand Down
1 change: 1 addition & 0 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use legion::query::View;
use legion::query::{IntoQuery, ViewElement};
use legion::storage::Component;

/// A query that references a given world.
pub struct QueryBorrow<'a, Q>
where
Q: Query,
Expand Down
14 changes: 14 additions & 0 deletions src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use crate::{OwnedResources, ResourcesProvider, World};

#[doc(hidden)]
pub trait RawSystem: Send + Sync + 'static {
/// Runs the system with the given resources and world.
fn run(&self, resources: &ResourcesEnum, world: &mut World, executor: &Executor);

/// Set up the system with the given resources and world.
fn set_up(&mut self, resources: &mut OwnedResources, world: &mut World);
}

Expand All @@ -22,29 +25,40 @@ impl Executor {
Self::default()
}

/// Adds the given system to the executor.
pub fn add(&mut self, system: impl RawSystem) {
self.add_boxed(Box::new(system));
}

/// Adds the given system to the exectuor.
pub fn add_boxed(&mut self, system: Box<dyn RawSystem>) {
self.systems.push(system);
}

/// Adds the given system to the executor.
///
/// Returns `Self` such that method calls for `Executor` can be chained.
pub fn with(mut self, system: impl RawSystem) -> Self {
self.add(system);
self
}

/// Returns the number of system registrede for this executor.
pub fn num_systems(&self) -> usize {
self.systems.len()
}

/// Setsup each system registred for this executor.
///
/// # Note
/// This function should only be called once.
pub fn set_up(&mut self, resources: &mut OwnedResources, world: &mut World) {
for system in &mut self.systems {
system.set_up(resources, world);
}
}

/// Executes the systems in series.
pub fn execute(&self, resources: &impl ResourcesProvider, world: &mut World) {
for system in &self.systems {
system.run(&resources.as_resources_ref(), world, self);
Expand Down
73 changes: 71 additions & 2 deletions src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,47 @@ use legion::borrow::{Ref, RefMut};
use legion::entity::Entity;
use legion::query::IntoQuery;
use legion::storage::Component;
use legion::world::EntityMutationError;
use legion::world::IntoComponentSource;
use legion::world::{ComponentTypeTupleSet, EntityMutationError, IntoComponentSource};

type LegionWorld = legion::world::World;

/// Contains queryable collections of data associated with `Entity`s.
#[derive(Default)]
pub struct World {
inner: LegionWorld,
}

impl World {
/// Creates a new Fecs World
pub fn new() -> Self {
World {
inner: LegionWorld::default(),
}
}

/// Spawns multiple new entities into the world with the given components,
/// the `EntityBuilder` and `BuiltEntity::spawn_in` is prefered for spawning
/// a single entity. You can use the `EntityBuilder::build` to create multiple
/// entities, this method can then be used to batch insert them.
///
/// Returns a slice of entity handlers for the spawned entities.
pub fn spawn(&mut self, components: impl IntoComponentSource) -> &[Entity] {
self.inner.insert((), components)
}

/// Despawns the given `Entity` from the `World`.
///
/// Returns `true` if the entity was despawned; else `false`.
pub fn despawn(&mut self, entity: Entity) -> bool {
self.inner.delete(entity)
}

/// Adds a component to an entity, or sets its value if the component is already present.
///
/// # Notes
/// This function has the overhead of moving the entity to either an existing or new archetype,
/// causing a memory copy of the entity to a new location. This function should not be used
/// multiple times in successive order.
pub fn add(
&mut self,
entity: Entity,
Expand All @@ -37,13 +53,37 @@ impl World {
self.inner.add_component(entity, component)
}

/// Removes a component from an entity.
///
/// # Notes
/// This function has the overhead of moving the entity to either an existing or new archetype,
/// causing a memory copy of the entity to a new location. This function should not be used
/// multiple times in successive order.
///
/// `World::batch_remove` should be used for removing multiple components from an entity at once.,
pub fn remove<C>(&mut self, entity: Entity) -> Result<(), EntityMutationError>
where
C: Component,
{
self.inner.remove_component::<C>(entity)
}

/// Removes multiple components from an entity
///
/// # Notes
/// This function is provided for bulk deleting components from an entity. This difference between this
/// function and `remove_component` is this allows us to remove multiple components and still only
/// perform a single move operation of the entity.
pub fn batch_remove<C>(&mut self, entity: Entity) -> Result<(), EntityMutationError>
where
C: ComponentTypeTupleSet,
{
self.inner.remove_components::<C>(entity)
}

/// Borrows component data `C` for the given entity.
///
/// Panics if the entity was not found or did not contain the specified component.
pub fn get<C>(&self, entity: Entity) -> Ref<C>
where
C: Component,
Expand All @@ -56,6 +96,9 @@ impl World {
})
}

/// Mutably borrows component data `C` for the given entity.
///
/// Panics if the neity was not found or did not contain the specified component.
pub fn get_mut<C>(&mut self, entity: Entity) -> RefMut<C>
where
C: Component,
Expand Down Expand Up @@ -83,13 +126,21 @@ impl World {
})
}

/// Borrows component data `C` for the given entity.
///
/// Returns `Some(data)` if the entity was found and contains the specified data.
/// Otherwise `None` is returned.
pub fn try_get<C>(&self, entity: Entity) -> Option<Ref<C>>
where
C: Component,
{
self.inner.get_component(entity)
}

/// Mutably borrows component data `C` for the given entity.
///
/// Returns `Some(data)` if the entity was found and contains the specified data.
/// Otherwise `None` is returned.
pub fn try_get_mut<C>(&mut self, entity: Entity) -> Option<RefMut<C>>
where
C: Component,
Expand All @@ -107,13 +158,18 @@ impl World {
self.inner.get_component_mut_unchecked(entity)
}

/// Checks if the given entity contains the component `C`.
pub fn has<C>(&self, entity: Entity) -> bool
where
C: Component,
{
self.try_get::<C>(entity).is_some()
}

/// Creates a refrence for the world and the given entity.
///
/// Returns `Some(refrence)` if the entity is alive otherwise.
/// Otherwise `None` is returned.
pub fn entity(&self, entity: Entity) -> Option<EntityRef> {
if self.is_alive(entity) {
Some(EntityRef {
Expand All @@ -125,6 +181,7 @@ impl World {
}
}

/// Creates a query for the world.
pub fn query<Q>(&mut self) -> QueryBorrow<Q>
where
Q: Query,
Expand All @@ -135,22 +192,34 @@ impl World {
}
}

/// Determines if the given `Entity` is alive within this `World`.
pub fn is_alive(&self, entity: Entity) -> bool {
self.inner.is_alive(entity)
}

/// Iteratively defragments the world's internal memory.
///
/// This compacts entities into fewer more continuous chunks.
///
/// `budget` describes the maximum number of entities that can be moved
/// in one call. Subsequent calls to `defrag` will resume progress from the
/// previous call.
pub fn defrag(&mut self, budget: Option<usize>) {
self.inner.defrag(budget)
}

/// Delete all entities and their associated data.
/// This leaves subscriptions and the command buffer intact.
pub fn clear(&mut self) {
self.inner.delete_all()
}

/// Borrows `Legion::World` which `Fecs::World` is based on.
pub fn inner(&self) -> &LegionWorld {
&self.inner
}

/// Mutable borrows `Legion::World` which `Fecs::World` is based on.
pub fn inner_mut(&mut self) -> &mut LegionWorld {
&mut self.inner
}
Expand Down