bevy_ecs/system/
adapter_system.rs1use alloc::vec::Vec;
2use bevy_utils::prelude::DebugName;
3
4use super::{IntoSystem, ReadOnlySystem, RunSystemError, System, SystemParamValidationError};
5use crate::{
6 schedule::InternedSystemSet,
7 system::{input::SystemInput, SystemIn},
8 world::unsafe_world_cell::UnsafeWorldCell,
9};
10
11#[diagnostic::on_unimplemented(
49 message = "`{Self}` can not adapt a system of type `{S}`",
50 label = "invalid system adapter"
51)]
52pub trait Adapt<S: System>: Send + Sync + 'static {
53 type In: SystemInput;
55 type Out;
57
58 fn adapt(
61 &mut self,
62 input: <Self::In as SystemInput>::Inner<'_>,
63 run_system: impl FnOnce(SystemIn<'_, S>) -> Result<S::Out, RunSystemError>,
64 ) -> Result<Self::Out, RunSystemError>;
65}
66
67#[derive(Clone)]
69pub struct IntoAdapterSystem<Func, S> {
70 func: Func,
71 system: S,
72}
73
74impl<Func, S> IntoAdapterSystem<Func, S> {
75 pub const fn new(func: Func, system: S) -> Self {
77 Self { func, system }
78 }
79}
80
81#[doc(hidden)]
82pub struct IsAdapterSystemMarker;
83
84impl<Func, S, I, O, M> IntoSystem<Func::In, Func::Out, (IsAdapterSystemMarker, I, O, M)>
85 for IntoAdapterSystem<Func, S>
86where
87 Func: Adapt<S::System>,
88 I: SystemInput,
89 S: IntoSystem<I, O, M>,
90{
91 type System = AdapterSystem<Func, S::System>;
92
93 fn into_system(this: Self) -> Self::System {
95 let system = IntoSystem::into_system(this.system);
96 let name = system.name();
97 AdapterSystem::new(this.func, system, name)
98 }
99}
100
101#[derive(Clone)]
103pub struct AdapterSystem<Func, S> {
104 func: Func,
105 system: S,
106 name: DebugName,
107}
108
109impl<Func, S> AdapterSystem<Func, S>
110where
111 Func: Adapt<S>,
112 S: System,
113{
114 pub const fn new(func: Func, system: S, name: DebugName) -> Self {
116 Self { func, system, name }
117 }
118}
119
120impl<Func, S> System for AdapterSystem<Func, S>
121where
122 Func: Adapt<S>,
123 S: System,
124{
125 type In = Func::In;
126 type Out = Func::Out;
127
128 fn name(&self) -> DebugName {
129 self.name.clone()
130 }
131
132 #[inline]
133 fn flags(&self) -> super::SystemStateFlags {
134 self.system.flags()
135 }
136
137 #[inline]
138 unsafe fn run_unsafe(
139 &mut self,
140 input: SystemIn<'_, Self>,
141 world: UnsafeWorldCell,
142 ) -> Result<Self::Out, RunSystemError> {
143 self.func.adapt(input, |input| unsafe {
145 self.system.run_unsafe(input, world)
146 })
147 }
148
149 #[cfg(feature = "hotpatching")]
150 #[inline]
151 fn refresh_hotpatch(&mut self) {
152 self.system.refresh_hotpatch();
153 }
154
155 #[inline]
156 fn apply_deferred(&mut self, world: &mut crate::prelude::World) {
157 self.system.apply_deferred(world);
158 }
159
160 #[inline]
161 fn queue_deferred(&mut self, world: crate::world::DeferredWorld) {
162 self.system.queue_deferred(world);
163 }
164
165 #[inline]
166 unsafe fn validate_param_unsafe(
167 &mut self,
168 world: UnsafeWorldCell,
169 ) -> Result<(), SystemParamValidationError> {
170 unsafe { self.system.validate_param_unsafe(world) }
172 }
173
174 fn initialize(&mut self, world: &mut crate::prelude::World) -> crate::query::FilteredAccessSet {
175 self.system.initialize(world)
176 }
177
178 fn check_change_tick(&mut self, check: crate::component::CheckChangeTicks) {
179 self.system.check_change_tick(check);
180 }
181
182 fn default_system_sets(&self) -> Vec<InternedSystemSet> {
183 self.system.default_system_sets()
184 }
185
186 fn get_last_run(&self) -> crate::component::Tick {
187 self.system.get_last_run()
188 }
189
190 fn set_last_run(&mut self, last_run: crate::component::Tick) {
191 self.system.set_last_run(last_run);
192 }
193}
194
195unsafe impl<Func, S> ReadOnlySystem for AdapterSystem<Func, S>
197where
198 Func: Adapt<S>,
199 S: ReadOnlySystem,
200{
201}
202
203impl<F, S, Out> Adapt<S> for F
204where
205 F: Send + Sync + 'static + FnMut(S::Out) -> Out,
206 S: System,
207{
208 type In = S::In;
209 type Out = Out;
210
211 fn adapt(
212 &mut self,
213 input: <Self::In as SystemInput>::Inner<'_>,
214 run_system: impl FnOnce(SystemIn<'_, S>) -> Result<S::Out, RunSystemError>,
215 ) -> Result<Self::Out, RunSystemError> {
216 run_system(input).map(self)
217 }
218}