2020-11-16 04:32:23 +00:00
|
|
|
use crate::{ArchetypeComponent, Resources, TypeAccess, World};
|
2020-08-29 00:08:51 +00:00
|
|
|
use std::{any::TypeId, borrow::Cow};
|
2020-07-10 04:18:35 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
2020-09-18 00:16:38 +00:00
|
|
|
pub struct SystemId(pub usize);
|
2020-07-10 04:18:35 +00:00
|
|
|
|
|
|
|
impl SystemId {
|
2020-08-16 07:30:04 +00:00
|
|
|
#[allow(clippy::new_without_default)]
|
2020-07-10 04:18:35 +00:00
|
|
|
pub fn new() -> Self {
|
2020-09-18 00:16:38 +00:00
|
|
|
SystemId(rand::random::<usize>())
|
2020-07-10 04:18:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-16 03:27:41 +00:00
|
|
|
/// An ECS system that can be added to a [Schedule](crate::Schedule)
|
2020-11-17 02:18:00 +00:00
|
|
|
pub trait System: Send + Sync + 'static {
|
2020-12-13 02:04:42 +00:00
|
|
|
type In;
|
|
|
|
type Out;
|
2020-07-10 04:18:35 +00:00
|
|
|
fn name(&self) -> Cow<'static, str>;
|
|
|
|
fn id(&self) -> SystemId;
|
2021-02-09 20:14:10 +00:00
|
|
|
fn update_access(&mut self, world: &World);
|
2020-10-30 06:39:55 +00:00
|
|
|
fn archetype_component_access(&self) -> &TypeAccess<ArchetypeComponent>;
|
2021-02-09 20:14:10 +00:00
|
|
|
fn component_access(&self) -> &TypeAccess<TypeId>;
|
2020-10-30 06:39:55 +00:00
|
|
|
fn resource_access(&self) -> &TypeAccess<TypeId>;
|
2021-02-09 20:14:10 +00:00
|
|
|
fn is_non_send(&self) -> bool;
|
2020-11-17 02:18:00 +00:00
|
|
|
/// # Safety
|
|
|
|
/// This might access World and Resources in an unsafe manner. This should only be called in one of the following contexts:
|
|
|
|
/// 1. This system is the only system running on the given World and Resources across all threads
|
|
|
|
/// 2. This system only runs in parallel with other systems that do not conflict with the `archetype_component_access()` or `resource_access()`
|
|
|
|
unsafe fn run_unsafe(
|
|
|
|
&mut self,
|
2020-12-13 02:04:42 +00:00
|
|
|
input: Self::In,
|
2020-11-17 02:18:00 +00:00
|
|
|
world: &World,
|
|
|
|
resources: &Resources,
|
2020-12-13 02:04:42 +00:00
|
|
|
) -> Option<Self::Out>;
|
2020-11-17 02:18:00 +00:00
|
|
|
fn run(
|
|
|
|
&mut self,
|
2020-12-13 02:04:42 +00:00
|
|
|
input: Self::In,
|
2020-11-17 02:18:00 +00:00
|
|
|
world: &mut World,
|
|
|
|
resources: &mut Resources,
|
2020-12-13 02:04:42 +00:00
|
|
|
) -> Option<Self::Out> {
|
2020-11-17 02:18:00 +00:00
|
|
|
// SAFE: world and resources are exclusively borrowed
|
|
|
|
unsafe { self.run_unsafe(input, world, resources) }
|
|
|
|
}
|
2021-02-09 20:14:10 +00:00
|
|
|
fn apply_buffers(&mut self, world: &mut World, resources: &mut Resources);
|
|
|
|
fn initialize(&mut self, world: &mut World, resources: &mut Resources);
|
2020-07-10 04:18:35 +00:00
|
|
|
}
|
2021-01-03 20:39:30 +00:00
|
|
|
|
|
|
|
pub type BoxedSystem<In = (), Out = ()> = Box<dyn System<In = In, Out = Out>>;
|