|
1 | 1 | //! Types that detect when their internal data mutate.
|
2 | 2 |
|
| 3 | +use crate::ptr::batch::{AlignedBatchGat, AlignedBatchT, AlignedBatchTrait}; |
| 4 | + |
3 | 5 | use crate::{component::ComponentTicks, ptr::PtrMut, system::Resource};
|
| 6 | +use std::marker::PhantomData; |
4 | 7 | #[cfg(feature = "bevy_reflect")]
|
5 | 8 | use std::ops::{Deref, DerefMut};
|
6 | 9 |
|
@@ -198,6 +201,15 @@ pub(crate) struct Ticks<'a> {
|
198 | 201 | pub(crate) change_tick: u32,
|
199 | 202 | }
|
200 | 203 |
|
| 204 | +pub(crate) struct TicksBatch<'a, const N: usize, const ALIGN: usize> |
| 205 | +where |
| 206 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 207 | +{ |
| 208 | + pub(crate) component_ticks: &'a mut AlignedBatchT<ComponentTicks, N, ALIGN>, |
| 209 | + pub(crate) last_change_tick: u32, |
| 210 | + pub(crate) change_tick: u32, |
| 211 | +} |
| 212 | + |
201 | 213 | /// Unique mutable borrow of a [`Resource`].
|
202 | 214 | ///
|
203 | 215 | /// See the [`Resource`] documentation for usage.
|
@@ -271,6 +283,143 @@ change_detection_impl!(Mut<'a, T>, T,);
|
271 | 283 | impl_into_inner!(Mut<'a, T>, T,);
|
272 | 284 | impl_debug!(Mut<'a, T>,);
|
273 | 285 |
|
| 286 | +/// Unique mutable borrow of an entity's component (batched version) |
| 287 | +/// a batch changes in unison. A batch has changed if any of its elements have changed. |
| 288 | +pub struct MutBatch<'a, T: ?Sized, const N: usize, const ALIGN: usize> |
| 289 | +where |
| 290 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 291 | + T: AlignedBatchGat<N, ALIGN>, |
| 292 | +{ |
| 293 | + pub(crate) value: &'a mut AlignedBatchT<T, N, ALIGN>, |
| 294 | + pub(crate) ticks: TicksBatch<'a, N, ALIGN>, |
| 295 | + pub(crate) _marker: PhantomData<T>, |
| 296 | +} |
| 297 | + |
| 298 | +impl<'a, T: ?Sized, const N: usize, const ALIGN: usize> DetectChanges for MutBatch<'a, T, N, ALIGN> |
| 299 | +where |
| 300 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 301 | + T: AlignedBatchGat<N, ALIGN>, |
| 302 | +{ |
| 303 | + #[inline] |
| 304 | + fn is_added(&self) -> bool { |
| 305 | + self.ticks |
| 306 | + .component_ticks |
| 307 | + .as_array() |
| 308 | + .iter() |
| 309 | + .any(|x| x.is_added(self.ticks.last_change_tick, self.ticks.change_tick)) |
| 310 | + } |
| 311 | + |
| 312 | + #[inline] |
| 313 | + fn is_changed(&self) -> bool { |
| 314 | + self.ticks |
| 315 | + .component_ticks |
| 316 | + .as_array() |
| 317 | + .iter() |
| 318 | + .any(|x| x.is_changed(self.ticks.last_change_tick, self.ticks.change_tick)) |
| 319 | + } |
| 320 | + |
| 321 | + #[inline] |
| 322 | + fn set_changed(&mut self) { |
| 323 | + for ticks in self.ticks.component_ticks.as_array_mut().iter_mut() { |
| 324 | + ticks.set_changed(self.ticks.change_tick); |
| 325 | + } |
| 326 | + } |
| 327 | + |
| 328 | + #[inline] |
| 329 | + fn last_changed(&self) -> u32 { |
| 330 | + self.ticks.last_change_tick |
| 331 | + } |
| 332 | + |
| 333 | + type Inner = AlignedBatchT<T, N, ALIGN>; |
| 334 | + |
| 335 | + fn set_last_changed(&mut self, last_change_tick: u32) { |
| 336 | + self.ticks.last_change_tick = last_change_tick; |
| 337 | + } |
| 338 | + |
| 339 | + fn bypass_change_detection(&mut self) -> &mut Self::Inner { |
| 340 | + self.value |
| 341 | + } |
| 342 | +} |
| 343 | + |
| 344 | +impl<'a, T, const N: usize, const ALIGN: usize> Deref for MutBatch<'a, T, N, ALIGN> |
| 345 | +where |
| 346 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 347 | + T: AlignedBatchGat<N, ALIGN>, |
| 348 | +{ |
| 349 | + type Target = AlignedBatchT<T, N, ALIGN>; |
| 350 | + |
| 351 | + #[inline] |
| 352 | + fn deref(&self) -> &Self::Target { |
| 353 | + self.value |
| 354 | + } |
| 355 | +} |
| 356 | + |
| 357 | +impl<'a, T, const N: usize, const ALIGN: usize> DerefMut for MutBatch<'a, T, N, ALIGN> |
| 358 | +where |
| 359 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 360 | + T: AlignedBatchGat<N, ALIGN>, |
| 361 | +{ |
| 362 | + #[inline] |
| 363 | + fn deref_mut(&mut self) -> &mut Self::Target { |
| 364 | + self.set_changed(); |
| 365 | + self.value |
| 366 | + } |
| 367 | +} |
| 368 | + |
| 369 | +impl<'a, T, const N: usize, const ALIGN: usize> AsRef<AlignedBatchT<T, N, ALIGN>> |
| 370 | + for MutBatch<'a, T, N, ALIGN> |
| 371 | +where |
| 372 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 373 | + T: AlignedBatchGat<N, ALIGN>, |
| 374 | +{ |
| 375 | + #[inline] |
| 376 | + fn as_ref(&self) -> &AlignedBatchT<T, N, ALIGN> { |
| 377 | + self.deref() |
| 378 | + } |
| 379 | +} |
| 380 | + |
| 381 | +impl<'a, T, const N: usize, const ALIGN: usize> AsMut<AlignedBatchT<T, N, ALIGN>> |
| 382 | + for MutBatch<'a, T, N, ALIGN> |
| 383 | +where |
| 384 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 385 | + T: AlignedBatchGat<N, ALIGN>, |
| 386 | +{ |
| 387 | + #[inline] |
| 388 | + fn as_mut(&mut self) -> &mut AlignedBatchT<T, N, ALIGN> { |
| 389 | + self.deref_mut() |
| 390 | + } |
| 391 | +} |
| 392 | + |
| 393 | +//change_detection_impl!(MutBatch<'a, T>, T,); |
| 394 | +//impl_into_inner!(MutBatch<'a, T>, T,); |
| 395 | +//impl_debug!(MutBatch<'a, T>,); |
| 396 | + |
| 397 | +impl<'a, T, const N: usize, const ALIGN: usize> MutBatch<'a, T, N, ALIGN> |
| 398 | +where |
| 399 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 400 | + T: AlignedBatchGat<N, ALIGN>, |
| 401 | +{ |
| 402 | + /// Consume `self` and return a mutable reference to the |
| 403 | + /// contained value while marking `self` as "changed". |
| 404 | + #[inline] |
| 405 | + pub fn into_inner(mut self) -> &'a mut AlignedBatchT<T, N, ALIGN> { |
| 406 | + self.set_changed(); |
| 407 | + self.value |
| 408 | + } |
| 409 | +} |
| 410 | + |
| 411 | +impl<'a, T, const N: usize, const ALIGN: usize> std::fmt::Debug for MutBatch<'a, T, N, ALIGN> |
| 412 | +where |
| 413 | + ComponentTicks: AlignedBatchGat<N, ALIGN>, |
| 414 | + T: AlignedBatchGat<N, ALIGN>, |
| 415 | + AlignedBatchT<T, N, ALIGN>: std::fmt::Debug, |
| 416 | + T: std::fmt::Debug, |
| 417 | +{ |
| 418 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 419 | + f.debug_tuple(stringify!($name)).field(&self.value).finish() |
| 420 | + } |
| 421 | +} |
| 422 | + |
274 | 423 | /// Unique mutable borrow of resources or an entity's component.
|
275 | 424 | ///
|
276 | 425 | /// Similar to [`Mut`], but not generic over the component type, instead
|
|
0 commit comments