bevy_ecs/system/
adapter_system.rs1use std::borrow::Cow;
2
3use super::{ReadOnlySystem, System};
4use crate::{schedule::InternedSystemSet, world::unsafe_world_cell::UnsafeWorldCell};
5
6#[diagnostic::on_unimplemented(
43 message = "`{Self}` can not adapt a system of type `{S}`",
44 label = "invalid system adapter"
45)]
46pub trait Adapt<S: System>: Send + Sync + 'static {
47 type In;
49 type Out;
51
52 fn adapt(&mut self, input: Self::In, run_system: impl FnOnce(S::In) -> S::Out) -> Self::Out;
55}
56
57#[derive(Clone)]
59pub struct AdapterSystem<Func, S> {
60 func: Func,
61 system: S,
62 name: Cow<'static, str>,
63}
64
65impl<Func, S> AdapterSystem<Func, S>
66where
67 Func: Adapt<S>,
68 S: System,
69{
70 pub const fn new(func: Func, system: S, name: Cow<'static, str>) -> Self {
72 Self { func, system, name }
73 }
74}
75
76impl<Func, S> System for AdapterSystem<Func, S>
77where
78 Func: Adapt<S>,
79 S: System,
80{
81 type In = Func::In;
82 type Out = Func::Out;
83
84 fn name(&self) -> Cow<'static, str> {
85 self.name.clone()
86 }
87
88 fn component_access(&self) -> &crate::query::Access<crate::component::ComponentId> {
89 self.system.component_access()
90 }
91
92 #[inline]
93 fn archetype_component_access(
94 &self,
95 ) -> &crate::query::Access<crate::archetype::ArchetypeComponentId> {
96 self.system.archetype_component_access()
97 }
98
99 fn is_send(&self) -> bool {
100 self.system.is_send()
101 }
102
103 fn is_exclusive(&self) -> bool {
104 self.system.is_exclusive()
105 }
106
107 fn has_deferred(&self) -> bool {
108 self.system.has_deferred()
109 }
110
111 #[inline]
112 unsafe fn run_unsafe(&mut self, input: Self::In, world: UnsafeWorldCell) -> Self::Out {
113 self.func.adapt(input, |input| unsafe {
115 self.system.run_unsafe(input, world)
116 })
117 }
118
119 #[inline]
120 fn run(&mut self, input: Self::In, world: &mut crate::prelude::World) -> Self::Out {
121 self.func
122 .adapt(input, |input| self.system.run(input, world))
123 }
124
125 #[inline]
126 fn apply_deferred(&mut self, world: &mut crate::prelude::World) {
127 self.system.apply_deferred(world);
128 }
129
130 #[inline]
131 fn queue_deferred(&mut self, world: crate::world::DeferredWorld) {
132 self.system.queue_deferred(world);
133 }
134
135 fn initialize(&mut self, world: &mut crate::prelude::World) {
136 self.system.initialize(world);
137 }
138
139 #[inline]
140 fn update_archetype_component_access(&mut self, world: UnsafeWorldCell) {
141 self.system.update_archetype_component_access(world);
142 }
143
144 fn check_change_tick(&mut self, change_tick: crate::component::Tick) {
145 self.system.check_change_tick(change_tick);
146 }
147
148 fn default_system_sets(&self) -> Vec<InternedSystemSet> {
149 self.system.default_system_sets()
150 }
151
152 fn get_last_run(&self) -> crate::component::Tick {
153 self.system.get_last_run()
154 }
155
156 fn set_last_run(&mut self, last_run: crate::component::Tick) {
157 self.system.set_last_run(last_run);
158 }
159}
160
161unsafe impl<Func, S> ReadOnlySystem for AdapterSystem<Func, S>
163where
164 Func: Adapt<S>,
165 S: ReadOnlySystem,
166{
167}
168
169impl<F, S, Out> Adapt<S> for F
170where
171 S: System,
172 F: Send + Sync + 'static + FnMut(S::Out) -> Out,
173{
174 type In = S::In;
175 type Out = Out;
176
177 fn adapt(&mut self, input: S::In, run_system: impl FnOnce(S::In) -> S::Out) -> Out {
178 self(run_system(input))
179 }
180}