1#[macro_export]
72macro_rules! define_plugin {
73 ($plugin_name:ident { $($config:tt)* }) => {
75 pub struct $plugin_name;
76
77 impl ::bevy::prelude::Plugin for $plugin_name {
78 fn build(&self, app: &mut ::bevy::prelude::App) {
79 $crate::define_plugin_internal!(app, $($config)*);
80 }
81
82 fn finish(&self, app: &mut ::bevy::prelude::App) {
83 $crate::define_plugin_finish!(app, $($config)*);
84 }
85 }
86 };
87}
88
89#[macro_export]
92macro_rules! define_plugin_internal {
93 ($app:ident,) => {};
95
96 ($app:ident, resources: [$($resource:ty),* $(,)?] $(, $($rest:tt)*)?) => {
98 $(
99 $app.init_resource::<$resource>();
100 )*
101 $crate::define_plugin_internal!($app, $($($rest)*)?);
102 };
103
104 ($app:ident, events: [$($event:ty),* $(,)?] $(, $($rest:tt)*)?) => {
106 $(
107 $app.add_event::<$event>();
108 )*
109 $crate::define_plugin_internal!($app, $($($rest)*)?);
110 };
111
112 ($app:ident, plugins: [$($plugin:expr),* $(,)?] $(, $($rest:tt)*)?) => {
114 $(
115 $app.add_plugins($plugin);
116 )*
117 $crate::define_plugin_internal!($app, $($($rest)*)?);
118 };
119
120 ($app:ident, states: [$($state:ty),* $(,)?] $(, $($rest:tt)*)?) => {
122 $(
123 $app.init_state::<$state>();
124 )*
125 $crate::define_plugin_internal!($app, $($($rest)*)?);
126 };
127
128 ($app:ident, sub_states: [$($state:ty),* $(,)?] $(, $($rest:tt)*)?) => {
130 $(
131 $app.add_sub_state::<$state>();
132 )*
133 $crate::define_plugin_internal!($app, $($($rest)*)?);
134 };
135
136 ($app:ident, reflect: [$($reflect_type:ty),* $(,)?] $(, $($rest:tt)*)?) => {
138 $(
139 $app.register_type::<$reflect_type>();
140 )*
141 $crate::define_plugin_internal!($app, $($($rest)*)?);
142 };
143
144 ($app:ident, startup: [$($system:expr),* $(,)?] $(, $($rest:tt)*)?) => {
146 $app.add_systems(
147 ::bevy::prelude::Startup,
148 ($($system,)*)
149 );
150 $crate::define_plugin_internal!($app, $($($rest)*)?);
151 };
152
153 ($app:ident, update: [$($system:expr),* $(,)?] $(, $($rest:tt)*)?) => {
155 $app.add_systems(
156 ::bevy::prelude::Update,
157 ($($system,)*)
158 );
159 $crate::define_plugin_internal!($app, $($($rest)*)?);
160 };
161
162 ($app:ident, fixed_update: [$($system:expr),* $(,)?] $(, $($rest:tt)*)?) => {
164 $app.add_systems(
165 ::bevy::prelude::FixedUpdate,
166 ($($system,)*)
167 );
168 $crate::define_plugin_internal!($app, $($($rest)*)?);
169 };
170
171 ($app:ident, on_enter: { $($state:expr => [$($system:expr),* $(,)?]),* $(,)? } $(, $($rest:tt)*)?) => {
173 $(
174 $app.add_systems(
175 ::bevy::prelude::OnEnter($state),
176 ($($system,)*)
177 );
178 )*
179 $crate::define_plugin_internal!($app, $($($rest)*)?);
180 };
181
182 ($app:ident, on_exit: { $($state:expr => [$($system:expr),* $(,)?]),* $(,)? } $(, $($rest:tt)*)?) => {
184 $(
185 $app.add_systems(
186 ::bevy::prelude::OnExit($state),
187 ($($system,)*)
188 );
189 )*
190 $crate::define_plugin_internal!($app, $($($rest)*)?);
191 };
192
193 ($app:ident, custom_init: $init_fn:expr $(, $($rest:tt)*)?) => {
195 $init_fn($app);
196 $crate::define_plugin_internal!($app, $($($rest)*)?);
197 };
198
199 ($app:ident, custom_finish: $finish_fn:expr $(, $($rest:tt)*)?) => {
201 $crate::define_plugin_internal!($app, $($($rest)*)?);
202 };
203
204 ($app:ident, $unknown:tt $($rest:tt)*) => {
206 compile_error!(concat!(
207 "Unknown plugin configuration option: ",
208 stringify!($unknown),
209 "\nSupported options: resources, events, plugins, states, sub_states, reflect, startup, update, fixed_update, on_enter, on_exit, custom_init, custom_finish"
210 ));
211 };
212}
213
214#[macro_export]
216macro_rules! define_plugin_finish {
217 ($app:ident,) => {};
219
220 ($app:ident, resources: [$($resource:ty),* $(,)?] $(, $($rest:tt)*)?) => {
222 $crate::define_plugin_finish!($app, $($($rest)*)?);
223 };
224 ($app:ident, events: [$($event:ty),* $(,)?] $(, $($rest:tt)*)?) => {
225 $crate::define_plugin_finish!($app, $($($rest)*)?);
226 };
227 ($app:ident, plugins: [$($plugin:expr),* $(,)?] $(, $($rest:tt)*)?) => {
228 $crate::define_plugin_finish!($app, $($($rest)*)?);
229 };
230 ($app:ident, startup: [$($system:expr),* $(,)?] $(, $($rest:tt)*)?) => {
231 $crate::define_plugin_finish!($app, $($($rest)*)?);
232 };
233 ($app:ident, update: [$($system:expr),* $(,)?] $(, $($rest:tt)*)?) => {
234 $crate::define_plugin_finish!($app, $($($rest)*)?);
235 };
236 ($app:ident, fixed_update: [$($system:expr),* $(,)?] $(, $($rest:tt)*)?) => {
237 $crate::define_plugin_finish!($app, $($($rest)*)?);
238 };
239 ($app:ident, on_enter: { $($state:expr => [$($system:expr),* $(,)?]),* $(,)? } $(, $($rest:tt)*)?) => {
240 $crate::define_plugin_finish!($app, $($($rest)*)?);
241 };
242 ($app:ident, on_exit: { $($state:expr => [$($system:expr),* $(,)?]),* $(,)? } $(, $($rest:tt)*)?) => {
243 $crate::define_plugin_finish!($app, $($($rest)*)?);
244 };
245 ($app:ident, custom_init: $init_fn:expr $(, $($rest:tt)*)?) => {
246 $crate::define_plugin_finish!($app, $($($rest)*)?);
247 };
248 ($app:ident, states: [$($state:ty),* $(,)?] $(, $($rest:tt)*)?) => {
249 $crate::define_plugin_finish!($app, $($($rest)*)?);
250 };
251 ($app:ident, sub_states: [$($state:ty),* $(,)?] $(, $($rest:tt)*)?) => {
252 $crate::define_plugin_finish!($app, $($($rest)*)?);
253 };
254 ($app:ident, reflect: [$($reflect_type:ty),* $(,)?] $(, $($rest:tt)*)?) => {
255 $crate::define_plugin_finish!($app, $($($rest)*)?);
256 };
257
258 ($app:ident, custom_finish: $finish_fn:expr $(, $($rest:tt)*)?) => {
260 $finish_fn($app);
261 $crate::define_plugin_finish!($app, $($($rest)*)?);
262 };
263
264 ($app:ident, $unknown:tt $($rest:tt)*) => {
266 $crate::define_plugin_finish!($app, $($rest)*);
267 };
268}
269
270