use crate::component::{ComponentSend, ComponentThreadLocal, Component,
OneToNComponentSend, OneToNComponentThreadLocal};
use crate::entity::{EntitiesCreation, Entity, EntityBuilder, EntityStoragesCreation};
use crate::storage::{HierarchicalStorage, OneToNStorage, Storage};
use crate::world::World;
use crate::storage::CreationSto;
use crate::{DebugParameter, ResourcesCreation};
pub trait EntitiesCreationExt<'a> {
fn with_entities_creation<'e, F, R>(&'e mut self, f: F) -> R
where F: FnOnce(EntitiesCreation<'e>) -> R;
fn new_entity(&mut self) -> EntityBuilder;
fn add_component_to<'r, C: ComponentSend>(&mut self, entity: &Entity, component: C)
where
for<'s> <C as Component>::Storage: Storage<'s, C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
{
self.with_entities_creation(|mut proxy| proxy.add_component_to(entity, component))
}
fn add_component_to_thread_local<'r, C: ComponentThreadLocal>(&mut self, entity: &Entity, component: C)
where
for<'s> <C as Component>::Storage: Storage<'s, C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
{
self.with_entities_creation(|mut proxy| proxy.add_component_to_thread_local(entity, component))
}
fn add_tag_to<C: 'static>(&mut self, entity: &Entity) {
self.with_entities_creation(|mut proxy| proxy.add_tag_to::<C>(entity))
}
fn add_child_component_to<'r, C: ComponentSend>(&mut self, parent: &Entity, entity: &Entity, component: C)
where
for<'b> <C as Component>::Storage: HierarchicalStorage<'b,C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
{
self.with_entities_creation(|mut proxy| proxy.add_child_component_to(parent, entity, component))
}
fn add_child_component_to_thread_local<'r, C: ComponentThreadLocal>(&mut self, parent: &Entity, entity: &Entity, component: C)
where
for<'b> <C as Component>::Storage: HierarchicalStorage<'b,C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
{
self.with_entities_creation(|mut proxy| proxy.add_child_component_to_thread_local(parent, entity, component))
}
fn add_slice_component_to<'r, C, I>(&mut self, entity: &Entity, component: I)
where
C: OneToNComponentSend,
for<'s> <C as Component>::Storage: OneToNStorage<'s, C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
I: IntoIterator<Item = C>
{
self.with_entities_creation(|mut proxy| proxy.add_slice_component_to(entity, component))
}
fn add_slice_component_to_thread_local<'r, C, I>(&mut self, entity: &Entity, component: I)
where
C: OneToNComponentThreadLocal,
for<'s> <C as Component>::Storage: OneToNStorage<'s, C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
I: IntoIterator<Item = C>
{
self.with_entities_creation(|mut proxy| proxy.add_slice_component_to_thread_local(entity, component))
}
fn remove_component_from<'r, C: Component>(&mut self, entity: &Entity)
where
for<'s> <C as Component>::Storage: Storage<'s, C>,
<<C as Component>::Storage as Storage<'r, C>>::Get: DebugParameter,
{
self.with_entities_creation(|mut proxy| proxy.remove_component_from::<C>(entity))
}
fn remove_entity(&mut self, entity: &Entity) {
self.with_entities_creation(|mut proxy| proxy.remove_entity(entity))
}
fn creation_storage<C: Component>(&mut self) -> CreationSto<C>;
}
pub trait ResourcesCreationExt {
fn with_resources_creation<F, R>(&mut self, f: F) -> R
where F: FnOnce(ResourcesCreation) -> R;
fn add_resource<T: 'static + Send>(&mut self, resource: T) {
self.with_resources_creation(|mut resources| resources.add_resource(resource))
}
fn remove_resource<T: 'static>(&mut self) -> Option<T>{
self.with_resources_creation(|mut resources| resources.remove_resource())
}
fn add_resource_thread_local<T: 'static>(&mut self, resource: T) {
self.with_resources_creation(|mut proxy| proxy.add_resource_thread_local(resource))
}
fn add_resource_as_trait<T, U, F, FMut>(&mut self, resource: (T, F, FMut))
where
T: 'static + Send,
U: 'static + Send + ?Sized,
F: Fn(&T) -> &U + 'static,
FMut: Fn(&mut T) -> &mut U + 'static
{
self.with_resources_creation(|mut proxy| proxy.add_resource_as_trait(resource))
}
fn add_resource_as_trait_thread_local<T, U, F, FMut>(&mut self, resource: (T, F, FMut))
where
T: 'static,
U: 'static + ?Sized,
F: Fn(&T) -> &U + 'static,
FMut: Fn(&mut T) -> &mut U + 'static
{
self.with_resources_creation(|mut proxy| proxy.add_resource_as_trait_thread_local(resource))
}
}
pub trait CreationContextExt<'a>: EntitiesCreationExt<'a> + ResourcesCreationExt {
fn with_entities_and_resources_creation<'e, F, R>(&'e mut self, f: F) -> R
where F: FnOnce(EntitiesCreation<'e>, ResourcesCreation<'e>) -> R;
}
impl<'a> EntitiesCreationExt<'a> for EntitiesCreation<'a>{
fn with_entities_creation<'e, F, R>(&'e mut self, f: F) -> R
where F: FnOnce(EntitiesCreation<'e>) -> R
{
f(EntitiesCreation{
storages: self.storages.clone(),
next_guid: self.next_guid,
})
}
fn new_entity(&mut self) -> EntityBuilder{
self.new_entity()
}
fn creation_storage<C: Component>(&mut self) -> CreationSto<C> {
self.storages_mut().creation_storage()
}
}
impl<'a> EntitiesCreationExt<'a> for EntityStoragesCreation<'a>{
fn with_entities_creation<'e, F, R>(&'e mut self, f: F) -> R
where F: FnOnce(EntitiesCreation<'e>) -> R
{
f(EntitiesCreation{
storages: self.storages.clone(),
next_guid: self.next_guid,
})
}
fn new_entity(&mut self) -> EntityBuilder{
self.new_entity()
}
fn creation_storage<C: Component>(&mut self) -> CreationSto<C> {
self.storages_mut().creation_storage()
}
}
impl<'a> ResourcesCreationExt for ResourcesCreation<'a> {
fn with_resources_creation<F, R>(&mut self, f: F) -> R
where F: FnOnce(ResourcesCreation) -> R {
f(self.clone())
}
}
impl<'a> EntitiesCreationExt<'a> for World{
fn with_entities_creation<'e, F, R>(&'e mut self, f: F) -> R
where F: FnOnce(EntitiesCreation<'e>) -> R
{
let creation_proxy = self.entities_creation();
f(creation_proxy)
}
fn new_entity(&mut self) -> EntityBuilder{
self.new_entity()
}
fn creation_storage<C: Component>(&mut self) -> CreationSto<C> {
self.creation_storage()
}
}
impl ResourcesCreationExt for World {
fn with_resources_creation<F, R>(&mut self, f: F) -> R
where F: FnOnce(ResourcesCreation) -> R {
f(self.resources_creation())
}
}