packet systems prototype.
This commit is contained in:
parent
6792cebfd0
commit
07402169ee
@ -344,6 +344,35 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
|
|||||||
#relationship_target
|
#relationship_target
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
pub fn derive_packet(input: TokenStream) -> TokenStream {
|
||||||
|
let mut ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
let bevy_ecs_path: Path = crate::bevy_ecs_path();
|
||||||
|
|
||||||
|
ast.generics
|
||||||
|
.make_where_clause()
|
||||||
|
.predicates
|
||||||
|
.push(parse_quote! { Self: Send + Sync + 'static });
|
||||||
|
|
||||||
|
let struct_name = &ast.ident;
|
||||||
|
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
|
||||||
|
let inner_generic = if type_generics.to_token_stream().is_empty() {
|
||||||
|
quote! {}
|
||||||
|
} else {
|
||||||
|
quote! {<'i>}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ts = TokenStream::from(quote! {
|
||||||
|
impl #impl_generics #bevy_ecs_path::packet::Packet for #struct_name #type_generics #where_clause { }
|
||||||
|
impl #impl_generics #bevy_ecs_path::packet::SystemInput for #struct_name #type_generics {
|
||||||
|
type Param<'i> = #struct_name #inner_generic;
|
||||||
|
type Inner<'i> = #struct_name #inner_generic;
|
||||||
|
fn wrap(this: Self::Inner<'_>) -> Self::Param<'_> {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
const ENTITIES: &str = "entities";
|
const ENTITIES: &str = "entities";
|
||||||
|
|
||||||
|
@ -672,6 +672,10 @@ pub fn derive_component(input: TokenStream) -> TokenStream {
|
|||||||
component::derive_component(input)
|
component::derive_component(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(Packet)]
|
||||||
|
pub fn derive_packet(input: TokenStream) -> TokenStream {
|
||||||
|
component::derive_packet(input)
|
||||||
|
}
|
||||||
/// Implement the `FromWorld` trait.
|
/// Implement the `FromWorld` trait.
|
||||||
#[proc_macro_derive(FromWorld, attributes(from_world))]
|
#[proc_macro_derive(FromWorld, attributes(from_world))]
|
||||||
pub fn derive_from_world(input: TokenStream) -> TokenStream {
|
pub fn derive_from_world(input: TokenStream) -> TokenStream {
|
||||||
|
@ -38,6 +38,7 @@ pub mod entity;
|
|||||||
pub mod entity_disabling;
|
pub mod entity_disabling;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
|
pub mod packet;
|
||||||
pub mod hierarchy;
|
pub mod hierarchy;
|
||||||
pub mod intern;
|
pub mod intern;
|
||||||
pub mod label;
|
pub mod label;
|
||||||
|
105
crates/bevy_ecs/src/packet/exclusivepacketsystem.rs
Normal file
105
crates/bevy_ecs/src/packet/exclusivepacketsystem.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
use crate::{component::{ComponentId, Tick}, system::{ExclusiveFunctionSystem, ExclusiveSystemParamFunction, IntoSystem, IsExclusiveFunctionSystem, System, SystemIn}, world::{unsafe_world_cell::UnsafeWorldCell, World}};
|
||||||
|
|
||||||
|
use super::{packetsystem::IntoPacketSystem, OptionPacket};
|
||||||
|
|
||||||
|
pub struct ExclusivePacketSystem<Marker, F>
|
||||||
|
where
|
||||||
|
F: ExclusiveSystemParamFunction<Marker>,
|
||||||
|
{
|
||||||
|
inner: ExclusiveFunctionSystem<Marker, F::Out, F>,
|
||||||
|
}
|
||||||
|
impl<Marker, F> IntoPacketSystem<F::In, F::Out, (IsExclusiveFunctionSystem, Marker)> for F
|
||||||
|
where
|
||||||
|
Marker: 'static,
|
||||||
|
F: ExclusiveSystemParamFunction<Marker>,
|
||||||
|
F::Out: OptionPacket,
|
||||||
|
{
|
||||||
|
type System = ExclusivePacketSystem<Marker, F>;
|
||||||
|
fn into_system(func: Self) -> Self::System {
|
||||||
|
ExclusivePacketSystem {
|
||||||
|
inner: IntoSystem::into_system(func)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Marker, F> System for ExclusivePacketSystem<Marker, F>
|
||||||
|
where
|
||||||
|
Marker: 'static,
|
||||||
|
F: ExclusiveSystemParamFunction<Marker>,
|
||||||
|
F::Out: OptionPacket,
|
||||||
|
{
|
||||||
|
type In = F::In;
|
||||||
|
type Out = ();
|
||||||
|
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_send(&self) -> bool {
|
||||||
|
self.inner.is_send()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_exclusive(&self) -> bool {
|
||||||
|
self.inner.is_exclusive()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn has_deferred(&self) -> bool {
|
||||||
|
self.inner.has_deferred()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&mut self, input: SystemIn<'_, Self>, world: &mut World) -> Result<Self::Out, crate::system::RunSystemError> {
|
||||||
|
let out = <ExclusiveFunctionSystem<Marker, F::Out, F> as System>::run(&mut self.inner, input, world)?;
|
||||||
|
out.run(world);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn apply_deferred(&mut self, world: &mut World) {
|
||||||
|
self.inner.apply_deferred(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn queue_deferred(&mut self, world: crate::world::DeferredWorld) {
|
||||||
|
self.inner.queue_deferred(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_last_run(&self) -> Tick {
|
||||||
|
self.inner.get_last_run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_last_run(&mut self, last_run: Tick) {
|
||||||
|
self.inner.set_last_run(last_run);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> bevy_utils::prelude::DebugName {
|
||||||
|
self.inner.name()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flags(&self) -> crate::system::SystemStateFlags {
|
||||||
|
self.inner.flags()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn run_unsafe(
|
||||||
|
&mut self,
|
||||||
|
_input: SystemIn<'_, Self>,
|
||||||
|
_world: UnsafeWorldCell,
|
||||||
|
) -> Result<Self::Out, crate::system::RunSystemError> {
|
||||||
|
panic!("exclusive system")
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn validate_param_unsafe(
|
||||||
|
&mut self,
|
||||||
|
world: UnsafeWorldCell,
|
||||||
|
) -> Result<(), crate::system::SystemParamValidationError> {
|
||||||
|
self.inner.validate_param_unsafe(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize(&mut self, world: &mut World) -> crate::query::FilteredAccessSet<ComponentId> {
|
||||||
|
self.inner.initialize(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_change_tick(&mut self, check: crate::component::CheckChangeTicks) {
|
||||||
|
self.inner.check_change_tick(check)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
213
crates/bevy_ecs/src/packet/mod.rs
Normal file
213
crates/bevy_ecs/src/packet/mod.rs
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
pub mod packetsystem;
|
||||||
|
pub mod exclusivepacketsystem;
|
||||||
|
mod optionpacket;
|
||||||
|
pub use optionpacket::OptionPacket;
|
||||||
|
use core::any::{type_name, TypeId};
|
||||||
|
use std::boxed::Box;
|
||||||
|
use crate::{system::Commands};
|
||||||
|
pub use crate::system::SystemInput;
|
||||||
|
use crate::system::System;
|
||||||
|
use packetsystem::IntoPacketSystem;
|
||||||
|
use smallvec::SmallVec;
|
||||||
|
use crate::{system::BoxedSystem, world::World};
|
||||||
|
pub use bevy_ecs_macros::Packet;
|
||||||
|
|
||||||
|
pub struct PacketInSystem<E: SystemInput> {
|
||||||
|
pub v: BoxedSystem<E, ()>,
|
||||||
|
pub tid: TypeId,
|
||||||
|
}
|
||||||
|
pub struct RegisteredSystems<E: SystemInput>{
|
||||||
|
pub v: SmallVec<[PacketInSystem<E>; 1]>,
|
||||||
|
}
|
||||||
|
pub trait Packet: Send + Sync + SystemInput + 'static { }
|
||||||
|
|
||||||
|
pub fn register_system<I, Out, F, M>(world: &mut World, f: F)
|
||||||
|
where
|
||||||
|
I: SystemInput + 'static,
|
||||||
|
Out: OptionPacket,
|
||||||
|
F: IntoPacketSystem<I, Out, M> + 'static,
|
||||||
|
M: 'static,
|
||||||
|
{
|
||||||
|
// don't forget to put it back.
|
||||||
|
let mut systems = world.remove_packet_system::<I>().unwrap_or_default();
|
||||||
|
|
||||||
|
let tid = TypeId::of::<F>();
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
for system in &systems.v {
|
||||||
|
assert_ne!(system.tid, tid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut system = IntoPacketSystem::into_system(f);
|
||||||
|
system.initialize(world);
|
||||||
|
let system = PacketInSystem { v: Box::new(system), tid };
|
||||||
|
systems.v.push(system);
|
||||||
|
|
||||||
|
// put back here.
|
||||||
|
world.put_back_packet_system(systems);
|
||||||
|
}
|
||||||
|
pub fn unregister_system<I, Out, F, M>(world: &mut World, _: F)
|
||||||
|
where
|
||||||
|
I: SystemInput + 'static,
|
||||||
|
Out: OptionPacket,
|
||||||
|
F: IntoPacketSystem<I, Out, M> + 'static,
|
||||||
|
M: 'static,
|
||||||
|
{
|
||||||
|
world.with_packet_system::<I>(|_, systems| {
|
||||||
|
let tid = TypeId::of::<F>();
|
||||||
|
systems.v.retain(|s| s.tid != tid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pub fn run_this_packet_system<'a, E>(packet: E, world: &mut World)
|
||||||
|
where
|
||||||
|
E: Packet,
|
||||||
|
for<'d> E: SystemInput<Inner<'d> = E>,
|
||||||
|
{
|
||||||
|
run_for_ref_packet(world, &packet);
|
||||||
|
run_for_val_packet(world, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_for_val_packet<E>(world: &mut World, event: E)
|
||||||
|
where
|
||||||
|
E: Packet,
|
||||||
|
E: for<'e> SystemInput<Inner<'e> = E>
|
||||||
|
{
|
||||||
|
world.with_packet_system::<E>(|world, systems| {
|
||||||
|
let mut systems_iter = systems.v.iter_mut();
|
||||||
|
let Some(system) = systems_iter.next() else { return };
|
||||||
|
system.v.run(event, world);
|
||||||
|
debug_assert!(systems_iter.len() == 0, "Only one system can take value {:?}", type_name::<E>());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_for_ref_packet<E>(world: &mut World, event: &E)
|
||||||
|
where
|
||||||
|
E: Packet,
|
||||||
|
{
|
||||||
|
world.with_packet_system::<&E>(|world, systems| {
|
||||||
|
for system in &mut systems.v {
|
||||||
|
system.v.run(event, world);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
impl<E: SystemInput> Default for RegisteredSystems<E> {
|
||||||
|
fn default() -> Self {
|
||||||
|
RegisteredSystems { v: Default::default()}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl World {
|
||||||
|
pub fn send<'a,'b,E>(&mut self, packet: E)
|
||||||
|
where
|
||||||
|
E: Packet,
|
||||||
|
E: for<'e> SystemInput<Inner<'e> = E>,
|
||||||
|
{
|
||||||
|
run_this_packet_system::<E>(packet, self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_packet_system<I, Out, F, M>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
I: SystemInput + 'static,
|
||||||
|
Out: OptionPacket,
|
||||||
|
F: IntoPacketSystem<I,Out, M> + 'static,
|
||||||
|
M: 'static,
|
||||||
|
{
|
||||||
|
register_system(self, f);
|
||||||
|
}
|
||||||
|
pub fn unregister_packet_system<I, Out, F, M>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
I: SystemInput + 'static,
|
||||||
|
Out: OptionPacket,
|
||||||
|
F: IntoPacketSystem<I,Out, M> + 'static,
|
||||||
|
M: 'static,
|
||||||
|
{
|
||||||
|
unregister_system(self, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_packet_system<I>(&mut self, f: impl FnOnce(&mut World, &mut RegisteredSystems<I>),)
|
||||||
|
where
|
||||||
|
I: SystemInput + 'static,
|
||||||
|
{
|
||||||
|
let Some(mut systems) = self.remove_packet_system::<I>() else {return};
|
||||||
|
f(self, &mut systems);
|
||||||
|
self.put_back_packet_system(systems);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// don't forget to put it back.
|
||||||
|
fn remove_packet_system<I: SystemInput + 'static>(&mut self) -> Option<Box<RegisteredSystems<I>>> {
|
||||||
|
let packet_systems = &mut self.packet_systems;
|
||||||
|
let rv = packet_systems.remove(&TypeId::of::<I>());
|
||||||
|
return rv.map(|v| v.downcast().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn put_back_packet_system<I: SystemInput + 'static>(&mut self, systems: Box<RegisteredSystems<I>>) {
|
||||||
|
let event_systems = &mut self.packet_systems;
|
||||||
|
let tid = TypeId::of::<I>();
|
||||||
|
debug_assert!(!event_systems.contains_key(&tid));
|
||||||
|
event_systems.insert(tid, systems);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
impl<'w,'s> Commands<'w,'s> {
|
||||||
|
pub fn send<E>(&mut self, packet: E)
|
||||||
|
where
|
||||||
|
E: Packet,
|
||||||
|
for<'e> E: SystemInput<Inner<'e> = E>,
|
||||||
|
{
|
||||||
|
self.queue(move |world: &mut World| world.send(packet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<E: Packet> SystemInput for &E {
|
||||||
|
type Param<'i> = &'i E;
|
||||||
|
type Inner<'i> = &'i E;
|
||||||
|
fn wrap(this: Self::Inner<'_>) -> Self::Param<'_> {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{system::ResMut, world::World};
|
||||||
|
use super::Packet;
|
||||||
|
use crate::resource::Resource;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct Count(u8);
|
||||||
|
|
||||||
|
#[derive(Packet)]
|
||||||
|
struct Input(u8);
|
||||||
|
|
||||||
|
#[derive(Packet)]
|
||||||
|
struct Moved;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let mut world = World::new();
|
||||||
|
world.insert_resource(Count(0));
|
||||||
|
world.register_packet_system(move_player);
|
||||||
|
world.register_packet_system(count_moved);
|
||||||
|
world.register_packet_system(count_moved1);
|
||||||
|
world.register_packet_system(count_moved2);
|
||||||
|
world.send(Input(b'a'));
|
||||||
|
let count = world.get_resource::<Count>().unwrap();
|
||||||
|
assert_eq!(count.0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_player(Input(input): Input) -> Option<Moved> {
|
||||||
|
match input {
|
||||||
|
b'a' => Some(Moved),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_moved1(_: &Moved, mut count: ResMut<Count>) {
|
||||||
|
count.0 += 1;
|
||||||
|
}
|
||||||
|
fn count_moved2(_: &Moved, mut count: ResMut<Count>) {
|
||||||
|
count.0 += 1;
|
||||||
|
}
|
||||||
|
fn count_moved(_: Moved, mut count: ResMut<Count>) {
|
||||||
|
count.0 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
69
crates/bevy_ecs/src/packet/optionpacket.rs
Normal file
69
crates/bevy_ecs/src/packet/optionpacket.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
use crate::world::World;
|
||||||
|
|
||||||
|
use super::{run_this_packet_system, Packet, SystemInput};
|
||||||
|
|
||||||
|
pub trait OptionPacket {
|
||||||
|
fn run(self, world: &mut World);
|
||||||
|
}
|
||||||
|
impl OptionPacket for (){ fn run(self, _: &mut World) {} }
|
||||||
|
|
||||||
|
impl<E: Packet> OptionPacket for E
|
||||||
|
where
|
||||||
|
for<'e> E: SystemInput<Inner<'e> = E>,
|
||||||
|
{
|
||||||
|
fn run(self, world: &mut World) {
|
||||||
|
run_this_packet_system::<E>(self, world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<O: OptionPacket> OptionPacket for Option<O> {
|
||||||
|
fn run(self, world: &mut World) {
|
||||||
|
let Some(event) = self else {return};
|
||||||
|
event.run(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macro_rules! impl_option_event_tuple {
|
||||||
|
($($param: ident),*) => {
|
||||||
|
impl<$($param: OptionPacket,)*> OptionPacket for ($($param,)*) {
|
||||||
|
fn run(self, world: &mut World) {
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
let ($($param,)*) = self;
|
||||||
|
$(
|
||||||
|
$param.run(world);
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_option_event_tuple!(O1);
|
||||||
|
impl_option_event_tuple!(O1, O2);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11, O12);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11, O12, O13);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11, O12, O13, O14);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11, O12, O13, O14, O15);
|
||||||
|
impl_option_event_tuple!(O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11, O12, O13, O14, O15, O16);
|
||||||
|
|
||||||
|
macro_rules! impl_option_packet_array {
|
||||||
|
($($N: literal),*) => {
|
||||||
|
$(
|
||||||
|
impl<O: OptionPacket> OptionPacket for [O;$N] {
|
||||||
|
fn run(self, world: &mut World) {
|
||||||
|
for packet in self {
|
||||||
|
packet.run(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_option_packet_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
|
110
crates/bevy_ecs/src/packet/packetsystem.rs
Normal file
110
crates/bevy_ecs/src/packet/packetsystem.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use crate::{
|
||||||
|
component::Tick,
|
||||||
|
system::{
|
||||||
|
FunctionSystem, IntoResult, IntoSystem, IsFunctionSystem, RunSystemError, System, SystemIn, SystemInput, SystemParamFunction
|
||||||
|
},
|
||||||
|
world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, World},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::OptionPacket;
|
||||||
|
|
||||||
|
pub trait IntoPacketSystem<In: SystemInput, Out, Marker>: Sized {
|
||||||
|
type System: System<In = In, Out = ()>;
|
||||||
|
fn into_system(this: Self) -> Self::System;
|
||||||
|
}
|
||||||
|
pub struct FunctionPacketSystem<Marker, F>
|
||||||
|
where
|
||||||
|
F: SystemParamFunction<Marker>,
|
||||||
|
{
|
||||||
|
inner: FunctionSystem<Marker, F::Out, F>,
|
||||||
|
}
|
||||||
|
impl<Marker, F> IntoPacketSystem<F::In, F::Out, (IsFunctionSystem, Marker)> for F
|
||||||
|
where
|
||||||
|
Marker: 'static,
|
||||||
|
F: SystemParamFunction<Marker>,
|
||||||
|
F::Out: OptionPacket,
|
||||||
|
{
|
||||||
|
type System = FunctionPacketSystem<Marker, F>;
|
||||||
|
fn into_system(func: Self) -> Self::System {
|
||||||
|
let inner = IntoSystem::into_system(func);
|
||||||
|
return FunctionPacketSystem { inner };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<Marker, F> System for FunctionPacketSystem<Marker, F>
|
||||||
|
where
|
||||||
|
Marker: 'static,
|
||||||
|
F: SystemParamFunction<Marker>,
|
||||||
|
F::Out: OptionPacket,
|
||||||
|
{
|
||||||
|
type In = F::In;
|
||||||
|
type Out = ();
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_send(&self) -> bool {
|
||||||
|
self.inner.is_send()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn is_exclusive(&self) -> bool {
|
||||||
|
self.inner.is_exclusive()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn has_deferred(&self) -> bool {
|
||||||
|
self.inner.has_deferred()
|
||||||
|
}
|
||||||
|
fn run(&mut self, input: SystemIn<'_, Self>, world: &mut World) -> Result<Self::Out, RunSystemError> {
|
||||||
|
let out = self.inner.run(input, world)?;
|
||||||
|
let rv = out.run(world);
|
||||||
|
return IntoResult::into_result(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn apply_deferred(&mut self, world: &mut World) {
|
||||||
|
self.inner.apply_deferred(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn queue_deferred(&mut self, world: DeferredWorld) {
|
||||||
|
self.inner.queue_deferred(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_last_run(&self) -> Tick {
|
||||||
|
self.inner.get_last_run()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_last_run(&mut self, last_run: Tick) {
|
||||||
|
self.inner.set_last_run(last_run);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flags(&self) -> crate::system::SystemStateFlags {
|
||||||
|
self.inner.flags()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> bevy_utils::prelude::DebugName {
|
||||||
|
self.inner.name()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn validate_param_unsafe(
|
||||||
|
&mut self,
|
||||||
|
world: UnsafeWorldCell,
|
||||||
|
) -> Result<(), crate::system::SystemParamValidationError> {
|
||||||
|
self.inner.validate_param_unsafe(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initialize(&mut self, world: &mut World) -> crate::query::FilteredAccessSet<crate::component::ComponentId> {
|
||||||
|
self.inner.initialize(world)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_change_tick(&mut self, check: crate::component::CheckChangeTicks) {
|
||||||
|
self.inner.check_change_tick(check)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn run_unsafe(
|
||||||
|
&mut self,
|
||||||
|
_input: SystemIn<'_, Self>,
|
||||||
|
_world: UnsafeWorldCell,
|
||||||
|
) -> Result<Self::Out, RunSystemError> {
|
||||||
|
unimplemented!("no multithreading, use run")
|
||||||
|
}
|
||||||
|
}
|
@ -106,6 +106,7 @@ pub struct World {
|
|||||||
pub(crate) last_check_tick: Tick,
|
pub(crate) last_check_tick: Tick,
|
||||||
pub(crate) last_trigger_id: u32,
|
pub(crate) last_trigger_id: u32,
|
||||||
pub(crate) command_queue: RawCommandQueue,
|
pub(crate) command_queue: RawCommandQueue,
|
||||||
|
pub(crate) packet_systems: bevy_platform::collections::HashMap<TypeId, Box<dyn core::any::Any>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for World {
|
impl Default for World {
|
||||||
@ -127,6 +128,7 @@ impl Default for World {
|
|||||||
last_trigger_id: 0,
|
last_trigger_id: 0,
|
||||||
command_queue: RawCommandQueue::new(),
|
command_queue: RawCommandQueue::new(),
|
||||||
component_ids: ComponentIds::default(),
|
component_ids: ComponentIds::default(),
|
||||||
|
packet_systems: Default::default(),
|
||||||
};
|
};
|
||||||
world.bootstrap();
|
world.bootstrap();
|
||||||
world
|
world
|
||||||
|
Loading…
Reference in New Issue
Block a user