2021-02-09 20:14:10 +00:00
|
|
|
use crate::{ArchetypeComponent, Resources, System, SystemId, TypeAccess, World};
|
2020-11-17 02:18:00 +00:00
|
|
|
use std::{any::TypeId, borrow::Cow};
|
|
|
|
|
|
|
|
pub struct ChainSystem<SystemA, SystemB> {
|
|
|
|
system_a: SystemA,
|
|
|
|
system_b: SystemB,
|
|
|
|
name: Cow<'static, str>,
|
|
|
|
id: SystemId,
|
2021-02-09 20:14:10 +00:00
|
|
|
archetype_component_access: TypeAccess<ArchetypeComponent>,
|
|
|
|
component_access: TypeAccess<TypeId>,
|
|
|
|
resource_access: TypeAccess<TypeId>,
|
2020-11-17 02:18:00 +00:00
|
|
|
}
|
|
|
|
|
2020-12-13 02:04:42 +00:00
|
|
|
impl<SystemA: System, SystemB: System<In = SystemA::Out>> System for ChainSystem<SystemA, SystemB> {
|
|
|
|
type In = SystemA::In;
|
|
|
|
type Out = SystemB::Out;
|
2020-11-17 02:18:00 +00:00
|
|
|
|
|
|
|
fn name(&self) -> Cow<'static, str> {
|
|
|
|
self.name.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn id(&self) -> SystemId {
|
|
|
|
self.id
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:14:10 +00:00
|
|
|
fn update_access(&mut self, world: &World) {
|
2020-11-17 02:18:00 +00:00
|
|
|
self.archetype_component_access.clear();
|
2021-02-09 20:14:10 +00:00
|
|
|
self.component_access.clear();
|
2020-11-17 02:18:00 +00:00
|
|
|
self.resource_access.clear();
|
2021-02-09 20:14:10 +00:00
|
|
|
self.system_a.update_access(world);
|
|
|
|
self.system_b.update_access(world);
|
2020-11-17 02:18:00 +00:00
|
|
|
|
|
|
|
self.archetype_component_access
|
2021-02-09 20:14:10 +00:00
|
|
|
.extend(self.system_a.archetype_component_access());
|
|
|
|
self.archetype_component_access
|
|
|
|
.extend(self.system_b.archetype_component_access());
|
|
|
|
self.component_access
|
|
|
|
.extend(self.system_a.component_access());
|
|
|
|
self.component_access
|
|
|
|
.extend(self.system_b.component_access());
|
|
|
|
self.resource_access.extend(self.system_a.resource_access());
|
|
|
|
self.resource_access.extend(self.system_b.resource_access());
|
2020-11-17 02:18:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn archetype_component_access(&self) -> &TypeAccess<ArchetypeComponent> {
|
|
|
|
&self.archetype_component_access
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:14:10 +00:00
|
|
|
fn component_access(&self) -> &TypeAccess<TypeId> {
|
|
|
|
&self.component_access
|
|
|
|
}
|
|
|
|
|
2020-11-17 02:18:00 +00:00
|
|
|
fn resource_access(&self) -> &TypeAccess<TypeId> {
|
|
|
|
&self.resource_access
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:14:10 +00:00
|
|
|
fn is_non_send(&self) -> bool {
|
|
|
|
self.system_a.is_non_send() || self.system_b.is_non_send()
|
2020-11-17 02:18:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
let out = self.system_a.run_unsafe(input, world, resources).unwrap();
|
|
|
|
self.system_b.run_unsafe(out, world, resources)
|
|
|
|
}
|
|
|
|
|
2021-02-09 20:14:10 +00:00
|
|
|
fn apply_buffers(&mut self, world: &mut World, resources: &mut Resources) {
|
|
|
|
self.system_a.apply_buffers(world, resources);
|
|
|
|
self.system_b.apply_buffers(world, resources);
|
2020-11-17 02:18:00 +00:00
|
|
|
}
|
2020-11-18 01:06:47 +00:00
|
|
|
|
|
|
|
fn initialize(&mut self, world: &mut World, resources: &mut Resources) {
|
|
|
|
self.system_a.initialize(world, resources);
|
|
|
|
self.system_b.initialize(world, resources);
|
|
|
|
}
|
2020-11-17 02:18:00 +00:00
|
|
|
}
|
|
|
|
|
2020-12-16 05:57:16 +00:00
|
|
|
pub trait IntoChainSystem<SystemB>: System + Sized
|
2020-11-17 02:18:00 +00:00
|
|
|
where
|
2020-12-16 05:57:16 +00:00
|
|
|
SystemB: System<In = Self::Out>,
|
2020-11-17 02:18:00 +00:00
|
|
|
{
|
2020-12-16 05:57:16 +00:00
|
|
|
fn chain(self, system: SystemB) -> ChainSystem<Self, SystemB>;
|
2020-11-17 02:18:00 +00:00
|
|
|
}
|
|
|
|
|
2020-12-16 05:57:16 +00:00
|
|
|
impl<SystemA, SystemB> IntoChainSystem<SystemB> for SystemA
|
2020-11-17 02:18:00 +00:00
|
|
|
where
|
|
|
|
SystemA: System,
|
2020-12-13 02:04:42 +00:00
|
|
|
SystemB: System<In = SystemA::Out>,
|
2020-11-17 02:18:00 +00:00
|
|
|
{
|
2020-12-16 05:57:16 +00:00
|
|
|
fn chain(self, system: SystemB) -> ChainSystem<SystemA, SystemB> {
|
2020-11-17 02:18:00 +00:00
|
|
|
ChainSystem {
|
2020-12-16 05:57:16 +00:00
|
|
|
name: Cow::Owned(format!("Chain({}, {})", self.name(), system.name())),
|
|
|
|
system_a: self,
|
|
|
|
system_b: system,
|
2020-11-17 02:18:00 +00:00
|
|
|
archetype_component_access: Default::default(),
|
2021-02-09 20:14:10 +00:00
|
|
|
component_access: Default::default(),
|
2020-11-17 02:18:00 +00:00
|
|
|
resource_access: Default::default(),
|
|
|
|
id: SystemId::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|