pi_world/
fetch.rs

1use std::borrow::Cow;
2use std::marker::PhantomData;
3use std::ops::{Deref, DerefMut};
4
5use pi_proc_macros::all_tuples;
6use pi_share::Share;
7
8use crate::archetype::{ArchetypeIndex, ComponentInfo, Row, COMPONENT_TICK};
9use crate::column::{BlobRef, Column};
10use crate::prelude::FromWorld;
11use crate::single_res::TickRes;
12use crate::system::{Relation, SystemMeta};
13use crate::world::{ComponentIndex, Entity, Tick, World};
14
15pub trait FetchComponents {
16    /// The item returned by this [`FetchComponents`]
17    type Item<'a>;
18    /// ReadOnly
19    type ReadOnly: FetchComponents;
20    /// Per archetype/table state used by this [`FetchComponents`] to fetch [`Self::Item`](crate::query::FetchComponents::Item)
21    type Fetch<'a>;
22
23    /// State used to construct a [`Self::Fetch`](crate::query::FetchComponents::Fetch). This will be cached inside [`QueryState`](crate::query::QueryState),
24    /// so it is best to move as much data / computation here as possible to reduce the cost of
25    /// constructing [`Self::Fetch`](crate::query::FetchComponents::Fetch).
26    type State: Send + Sync + Sized;
27
28    /// initializes ReadWrite for this [`FetchComponents`] type.
29    fn init_state(_world: &mut World, _meta: &mut SystemMeta) -> Self::State;
30
31    /// Creates a new instance of this fetch.
32    ///
33    /// # Safety
34    ///
35    /// - `world` must have permission to access any of the components specified in `Self::update_archetype_component_access`.
36    /// - `state` must have been initialized (via [`FetchComponents::init_statee`]) using the same `world` passed
37    ///   in to this function.
38    fn init_fetch<'w>(
39        world: &'w World,
40        state: &'w Self::State,
41        index: ArchetypeIndex,
42        tick: Tick,
43        last_run: Tick,
44    ) -> Self::Fetch<'w>;
45
46    fn init_fetch_opt<'w>(
47        world: &'w World,
48        state: &'w Self::State,
49        index: ArchetypeIndex,
50        tick: Tick,
51        last_run: Tick,
52    ) -> Option<Self::Fetch<'w>>;
53
54    /// Fetch [`Self::Item`](`FetchComponents::Item`) for either the given `entity` in the current [`Table`],
55    /// or for the given `entity` in the current [`Archetype`]. This must always be called after
56    /// [`FetchComponents::set_table`] with a `table_row` in the range of the current [`Table`] or after
57    /// [`FetchComponents::set_archetype`]  with a `entity` in the current archetype.
58    ///
59    /// # Safety
60    ///
61    /// Must always be called _after_ [`FetchComponents::set_table`] or [`FetchComponents::set_archetype`]. `entity` and
62    /// `table_row` must be in the range of the current table and archetype.
63    ///
64    /// If `update_component_access` includes any mutable accesses, then the caller must ensure
65    /// that `fetch` is called no more than once for each `entity`/`table_row` in each archetype.
66    /// If `Self` implements [`ReadOnlyFetchComponents`], then this can safely be called multiple times.
67    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w>;
68}
69
70impl FetchComponents for Entity {
71    type Fetch<'w> = ();
72    type Item<'w> = Entity;
73    type ReadOnly = Self;
74    type State = ();
75
76    fn init_state(_world: &mut World, _meta: &mut SystemMeta) -> Self::State {}
77    //#[inline]
78    fn init_fetch<'w>(
79        _world: &'w World,
80        _state: &'w Self::State,
81        _index: ArchetypeIndex,
82        _tick: Tick,
83        _last_run: Tick,
84    ) -> Self::Fetch<'w>{
85        ()
86    }
87
88    //#[inline]
89    fn init_fetch_opt<'w>(
90        _world: &'w World,
91        _state: &'w Self::State,
92        _index: ArchetypeIndex,
93        _tick: Tick,
94        _last_run: Tick,
95    ) -> Option<Self::Fetch<'w>>{
96        Some(())
97    }
98
99    //#[inline(always)]
100    fn fetch<'w>(_fetch: &Self::Fetch<'w>, _row: Row, e: Entity) -> Self::Item<'w> {
101        e
102    }
103}
104
105impl<T: 'static> FetchComponents for &T {
106    type Fetch<'w> = BlobRef<'w>; // 必须和&mut T的Fetch一致,因为Query做了Fetch的缓冲
107    type Item<'w> = &'w T;
108    type ReadOnly = Self;
109    type State = Share<Column>;
110
111    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
112        meta.component_relate(
113            world,
114            ComponentInfo::of::<T>(0),
115            Relation::Read(0usize.into()),
116        )
117        .1
118    }
119    //#[inline(always)]
120    fn init_fetch<'w>(
121        _world: &'w World,
122        state: &'w Self::State,
123        index: ArchetypeIndex,
124        _tick: Tick,
125        _last_run: Tick,
126    ) -> Self::Fetch<'w>{
127        state.blob_ref_unchecked(index)
128    }
129
130    //#[inline]
131    fn init_fetch_opt<'w>(
132        _world: &'w World,
133        state: &'w Self::State,
134        index: ArchetypeIndex,
135        _tick: Tick,
136        _last_run: Tick,
137    ) -> Option<Self::Fetch<'w>>{
138        state.blob_ref(index)
139    }
140
141    //#[inline(always)]
142    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, _e: Entity) -> Self::Item<'w> {
143        fetch.get_unchecked::<T>(row)
144    }
145}
146
147impl<T: 'static> FetchComponents for &mut T {
148    type Fetch<'w> = ColumnTick<'w>;
149    type Item<'w> = Mut<'w, T>;
150    type ReadOnly = &'static T;
151    type State = Share<Column>;
152
153    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
154        meta.component_relate(
155            world,
156            ComponentInfo::of::<T>(0),
157            Relation::Write(0usize.into()),
158        )
159        .1
160    }
161    //#[inline]
162    fn init_fetch<'w>(
163        _world: &'w World,
164        state: &'w Self::State,
165        index: ArchetypeIndex,
166        tick: Tick,
167        last_run: Tick,
168    )  -> Self::Fetch<'w>{
169        ColumnTick::new(state.blob_ref_unchecked(index), tick, last_run)
170    }
171
172    //#[inline]
173    fn init_fetch_opt<'w>(
174        _world: &'w World,
175        state: &'w Self::State,
176        index: ArchetypeIndex,
177        tick: Tick,
178        last_run: Tick,
179    )  -> Option<Self::Fetch<'w>>{
180        state.blob_ref(index).map(|r| {
181            ColumnTick::new(r, tick, last_run)
182        }) 
183    }
184
185    //#[inline(always)]
186    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
187        Mut::new(fetch, e, row)
188    }
189}
190
191pub struct Ref<T: 'static>(PhantomData<T>);
192impl<T: 'static> FetchComponents for Ref<T> {
193    type Fetch<'w> = ColumnTick<'w>;
194    type Item<'w> = TickRef<'w, T>;
195    type ReadOnly = Self;
196    type State = Share<Column>;
197
198    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
199        meta.component_relate(
200            world,
201            ComponentInfo::of::<T>(COMPONENT_TICK),
202            Relation::Read(0usize.into()),
203        )
204        .1
205    }
206    //#[inline]
207    fn init_fetch<'w>(
208        _world: &'w World,
209        state: &'w Self::State,
210        index: ArchetypeIndex,
211        tick: Tick,
212        last_run: Tick,
213    )  -> Self::Fetch<'w>{
214        ColumnTick::new(state.blob_ref_unchecked(index), tick, last_run)
215    }
216
217    //#[inline]
218    fn init_fetch_opt<'w>(
219        _world: &'w World,
220        state: &'w Self::State,
221        index: ArchetypeIndex,
222        tick: Tick,
223        last_run: Tick,
224    )  -> Option<Self::Fetch<'w>>{
225        state.blob_ref(index).map(|r| {
226            ColumnTick::new(r, tick, last_run)
227        }) 
228    }
229
230    //#[inline(always)]
231    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
232        TickRef::new(fetch, row, e)
233    }
234}
235
236impl<T: 'static> FetchComponents for Option<Ref<T>> {
237    type Fetch<'w> = Option<ColumnTick<'w>>;
238    type Item<'w> = Option<TickRef<'w, T>>;
239    type ReadOnly = Self;
240    type State = Share<Column>;
241
242    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
243        meta.component_relate(
244            world,
245            ComponentInfo::of::<T>(COMPONENT_TICK),
246            Relation::OptRead(0usize.into()),
247        )
248        .1
249    }
250    //#[inline]
251    fn init_fetch<'w>(
252        _world: &'w World,
253        state: &'w Self::State,
254        index: ArchetypeIndex,
255        tick: Tick,
256        last_run: Tick,
257    ) -> Self::Fetch<'w> {
258        if let Some(column) = state.blob_ref(index) {
259            Some(ColumnTick::new(column, tick, last_run))
260        } else {
261            None
262        }
263    }
264
265    //#[inline]
266    fn init_fetch_opt<'w>(
267        _world: &'w World,
268        state: &'w Self::State,
269        index: ArchetypeIndex,
270        tick: Tick,
271        last_run: Tick,
272    ) -> Option<Self::Fetch<'w>> {
273        Some(Self::init_fetch(_world, state, index, tick, last_run))
274    }
275
276    //#[inline(always)]
277    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
278        match fetch {
279            Some(c) => Some(TickRef::new(c, row, e)),
280            None => None,
281        }
282    }
283}
284
285impl<T: 'static> FetchComponents for Ticker<'_, &'_ T> {
286    type Fetch<'w> = ColumnTick<'w>;
287    type Item<'w> = Ticker<'w, &'w T>;
288    type ReadOnly = Ticker<'static, &'static T>;
289    type State = Share<Column>;
290
291    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
292        meta.component_relate(
293            world,
294            ComponentInfo::of::<T>(COMPONENT_TICK),
295            Relation::Read(0usize.into()),
296        )
297        .1
298    }
299    //#[inline]
300    fn init_fetch<'w>(
301        _world: &'w World,
302        state: &'w Self::State,
303        index: ArchetypeIndex,
304        tick: Tick,
305        last_run: Tick,
306    ) -> Self::Fetch<'w> {
307        ColumnTick::new(state.blob_ref_unchecked(index), tick, last_run)
308    }
309    //#[inline]
310    fn init_fetch_opt<'w>(
311        _world: &'w World,
312        state: &'w Self::State,
313        index: ArchetypeIndex,
314        tick: Tick,
315        last_run: Tick,
316    )  -> Option<Self::Fetch<'w>>{
317        state.blob_ref(index).map(|r| {
318            ColumnTick::new(r, tick, last_run)
319        }) 
320    }
321    //#[inline(always)]
322    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
323        Ticker::new(fetch, e, row)
324    }
325}
326
327impl<T: 'static> FetchComponents for Ticker<'_, &'_ mut T> {
328    type Fetch<'w> = ColumnTick<'w>;
329    type Item<'w> = Ticker<'w, &'w mut T>;
330    type ReadOnly = Ticker<'static, &'static T>;
331    type State = Share<Column>;
332
333    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
334        meta.component_relate(
335            world,
336            ComponentInfo::of::<T>(COMPONENT_TICK),
337            Relation::Write(0usize.into()),
338        )
339        .1
340    }
341    //#[inline]
342    fn init_fetch<'w>(
343        _world: &'w World,
344        state: &'w Self::State,
345        index: ArchetypeIndex,
346        tick: Tick,
347        last_run: Tick,
348    ) -> Self::Fetch<'w> {
349        ColumnTick::new(state.blob_ref_unchecked(index), tick, last_run)
350    }
351    //#[inline]
352    fn init_fetch_opt<'w>(
353        _world: &'w World,
354        state: &'w Self::State,
355        index: ArchetypeIndex,
356        tick: Tick,
357        last_run: Tick,
358    )  -> Option<Self::Fetch<'w>>{
359        state.blob_ref(index).map(|r| {
360            ColumnTick::new(r, tick, last_run)
361        }) 
362    }
363    //#[inline(always)]
364    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
365        Ticker::new(fetch, e, row)
366    }
367}
368
369impl<T: 'static> FetchComponents for Option<Ticker<'_, &'_ T>> {
370    type Fetch<'w> = Option<ColumnTick<'w>>;
371    type Item<'w> = Option<Ticker<'w, &'w T>>;
372    type ReadOnly = Option<Ticker<'static, &'static T>>;
373    type State = Share<Column>;
374
375    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
376        meta.component_relate(
377            world,
378            ComponentInfo::of::<T>(COMPONENT_TICK),
379            Relation::OptRead(0usize.into()),
380        )
381        .1
382    }
383    //#[inline]
384    fn init_fetch<'w>(
385        _world: &'w World,
386        state: &'w Self::State,
387        index: ArchetypeIndex,
388        tick: Tick,
389        last_run: Tick,
390    ) -> Self::Fetch<'w> {
391        if let Some(column) = state.blob_ref(index) {
392            Some(ColumnTick::new(column, tick, last_run))
393        } else {
394            None
395        }
396    }
397
398    //#[inline]
399    fn init_fetch_opt<'w>(
400        world: &'w World,
401        state: &'w Self::State,
402        index: ArchetypeIndex,
403        tick: Tick,
404        last_run: Tick,
405    )  -> Option<Self::Fetch<'w>>{
406        Some(Self::init_fetch(world, state, index, tick, last_run))
407    }
408    //#[inline(always)]
409    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
410        match fetch {
411            Some(f) => Some(Ticker::new(f, e, row)),
412            None => None,
413        }
414    }
415}
416
417impl<T: 'static> FetchComponents for Option<Ticker<'_, &'_ mut T>> {
418    type Fetch<'w> = Option<ColumnTick<'w>>;
419    type Item<'w> = Option<Ticker<'w, &'w mut T>>;
420    type ReadOnly = Option<Ticker<'static, &'static T>>;
421    type State = Share<Column>;
422
423    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
424        meta.component_relate(
425            world,
426            ComponentInfo::of::<T>(COMPONENT_TICK),
427            Relation::OptWrite(0usize.into()),
428        )
429        .1
430    }
431    //#[inline]
432    fn init_fetch<'w>(
433        _world: &'w World,
434        state: &'w Self::State,
435        index: ArchetypeIndex,
436        tick: Tick,
437        last_run: Tick,
438    ) -> Self::Fetch<'w> {
439        if let Some(column) = state.blob_ref(index) {
440            Some(ColumnTick::new(column, tick, last_run))
441        } else {
442            None
443        }
444    }
445    //#[inline]
446    fn init_fetch_opt<'w>(
447        world: &'w World,
448        state: &'w Self::State,
449        index: ArchetypeIndex,
450        tick: Tick,
451        last_run: Tick,
452    )  -> Option<Self::Fetch<'w>>{
453        Some(Self::init_fetch(world, state, index, tick, last_run))
454    }
455    //#[inline(always)]
456    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
457        match fetch {
458            Some(f) => Some(Ticker::new(f, e, row)),
459            None => None,
460        }
461    }
462}
463
464impl<T: 'static> FetchComponents for Option<&T> {
465    type Fetch<'w> = Option<ColumnTick<'w>>;
466    type Item<'w> = Option<&'w T>;
467    type ReadOnly = Self;
468    type State = Share<Column>;
469
470    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
471        meta.component_relate(
472            world,
473            ComponentInfo::of::<T>(0),
474            Relation::OptRead(0usize.into()),
475        )
476        .1
477    }
478    //#[inline]
479    fn init_fetch<'w>(
480        _world: &'w World,
481        state: &'w Self::State,
482        index: ArchetypeIndex,
483        tick: Tick,
484        last_run: Tick,
485    ) -> Self::Fetch<'w> {
486        if let Some(column) = state.blob_ref(index) {
487            Some(ColumnTick::new(column, tick, last_run))
488        } else {
489            None
490        }
491    }
492    //#[inline]
493    fn init_fetch_opt<'w>(
494        world: &'w World,
495        state: &'w Self::State,
496        index: ArchetypeIndex,
497        tick: Tick,
498        last_run: Tick,
499    )  -> Option<Self::Fetch<'w>>{
500        Some(Self::init_fetch(world, state, index, tick, last_run))
501    }
502    //#[inline(always)]
503    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, _e: Entity) -> Self::Item<'w> {
504        match fetch {
505            Some(c) => Some(c.column.get_unchecked::<T>(row)),
506            None => None,
507        }
508    }
509}
510
511impl<T: 'static> FetchComponents for Option<&mut T> {
512    type Fetch<'w> = Option<ColumnTick<'w>>;
513    type Item<'w> = Option<Mut<'w, T>>;
514    type ReadOnly = Option<&'static T>;
515    type State = Share<Column>;
516
517    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
518        meta.component_relate(
519            world,
520            ComponentInfo::of::<T>(0),
521            Relation::OptWrite(0usize.into()),
522        )
523        .1
524    }
525    //#[inline]
526    fn init_fetch<'w>(
527        _world: &'w World,
528        state: &'w Self::State,
529        index: ArchetypeIndex,
530        tick: Tick,
531        last_run: Tick,
532    ) -> Self::Fetch<'w> {
533        if let Some(column) = state.blob_ref(index) {
534            Some(ColumnTick::new(column, tick, last_run))
535        } else {
536            None
537        }
538    }
539    //#[inline]
540    fn init_fetch_opt<'w>(
541        world: &'w World,
542        state: &'w Self::State,
543        index: ArchetypeIndex,
544        tick: Tick,
545        last_run: Tick,
546    )  -> Option<Self::Fetch<'w>>{
547        Some(Self::init_fetch(world, state, index, tick, last_run))
548    }
549    //#[inline(always)]
550    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, e: Entity) -> Self::Item<'w> {
551        match fetch {
552            Some(f) => Some(Mut::new(f, e, row)),
553            None => None,
554        }
555    }
556}
557
558fn _init_state_ordefault(world: &mut World, meta: &mut SystemMeta, info: ComponentInfo) -> Share<Column> {
559    meta.add_res(Relation::Read(*info.type_id()));
560    let column = meta
561        .component_relate(world, info, Relation::OptRead(0usize.into()))
562        .1;
563    column
564}
565
566/// 不存在T时,使用默认值。
567/// 默认值取Res<DefaultValue<T>>
568/// DefaultValue<T>默认为DefaultValue::from_world的返回值,也可被应用程序覆盖
569pub struct OrDefault<T: 'static + FromWorld>(PhantomData<T>);
570impl<T: 'static + FromWorld> FetchComponents for OrDefault<T> {
571    type Fetch<'w> = Result<BlobRef<'w>, &'w T>;
572    type Item<'w> = &'w T;
573    type ReadOnly = Self;
574    type State = (Share<Column>, Share<TickRes<T>>);
575
576    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
577        let info = ComponentInfo::of::<T>(0);
578        let column = _init_state_ordefault(world, meta, info);
579        // meta.add_res(Relation::Read(*info.type_id()));
580        // let column = meta
581        //     .component_relate(world, info, Relation::OptRead(0usize.into()))
582        //     .1;
583        let _index = world.init_single_res::<T>();
584        (column, world.get_share_single_res::<T>().unwrap())
585    }
586    //#[inline]
587    fn init_fetch<'w>(
588        _world: &'w World,
589        state: &'w Self::State,
590        index: ArchetypeIndex,
591        _tick: Tick,
592        _last_run: Tick,
593    ) -> Self::Fetch<'w> {
594        if let Some(column) = state.0.blob_ref(index) {
595            Ok(column)
596        } else {
597            Err(&state.1)
598        }
599    }
600    //#[inline]
601    fn init_fetch_opt<'w>(
602        world: &'w World,
603        state: &'w Self::State,
604        index: ArchetypeIndex,
605        tick: Tick,
606        last_run: Tick,
607    ) -> Option<Self::Fetch<'w>> {
608        Some(Self::init_fetch(world, state, index, tick, last_run))
609    } 
610    //#[inline(always)]
611    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, _e: Entity) -> Self::Item<'w> {
612        match fetch {
613            Ok(c) => c.get_unchecked::<T>(row),
614            Err(r) => *r,
615        }
616    }
617}
618/// 不存在T时,使用默认值。
619/// 默认值取Res<DefaultValue<T>>
620/// DefaultValue<T>默认为DefaultValue::from_world的返回值,也可被应用程序覆盖
621pub struct OrDefaultRef<T: 'static + FromWorld>(PhantomData<T>);
622impl<T: 'static + FromWorld> FetchComponents for OrDefaultRef<T> {
623    type Fetch<'w> = Result<ColumnTick<'w>, (&'w T, Tick)>;
624    type Item<'w> = ValueRef<'w, T>;
625    type ReadOnly = Self;
626    type State = (Share<Column>, Share<TickRes<T>>);
627
628    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
629        let info = ComponentInfo::of::<T>(0);
630        let column = _init_state_ordefault(world, meta, info);
631        // meta.add_res(Relation::Read(*info.type_id()));
632        // let column = meta
633        //     .component_relate(world, info, Relation::OptRead(0usize.into()))
634        //     .1;
635        let _index = world.init_single_res::<T>();
636        (column, world.get_share_single_res::<T>().unwrap())
637    }
638    //#[inline]
639    fn init_fetch<'w>(
640        _world: &'w World,
641        state: &'w Self::State,
642        index: ArchetypeIndex,
643        tick: Tick,
644        last_run: Tick,
645    ) -> Self::Fetch<'w> {
646        if let Some(column) = state.0.blob_ref(index) {
647            Ok(ColumnTick::new(column, tick, last_run))
648        } else {
649            Err((&state.1, last_run))
650        }
651    }
652    //#[inline]
653    fn init_fetch_opt<'w>(
654        world: &'w World,
655        state: &'w Self::State,
656        index: ArchetypeIndex,
657        tick: Tick,
658        last_run: Tick,
659    ) -> Option<Self::Fetch<'w>> {
660        Some(Self::init_fetch(world, state, index, tick, last_run))
661    }
662    //#[inline(always)]
663    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, _e: Entity) -> Self::Item<'w> {
664        match fetch {
665            Ok(c) => {
666                let tick = c.column.get_tick_unchecked(row);
667                ValueRef::new(c.column.get_unchecked::<T>(row), tick, c.last_run)
668            }
669            Err(r) => ValueRef::new(r.0, 0usize.into(), r.1),
670        }
671    }
672}
673
674pub struct Has<T: 'static>(PhantomData<T>);
675impl<T: 'static> FetchComponents for Has<T> {
676    type Fetch<'w> = bool;
677    type Item<'w> = bool;
678    type ReadOnly = Self;
679    type State = Share<Column>;
680
681    fn init_state(world: &mut World, meta: &mut SystemMeta) -> Self::State {
682        meta.component_relate(
683            world,
684            ComponentInfo::of::<T>(0),
685            Relation::OptRead(0usize.into()),
686        )
687        .1
688    }
689    //#[inline]
690    fn init_fetch<'w>(
691        _world: &'w World,
692        state: &'w Self::State,
693        index: ArchetypeIndex,
694        _tick: Tick,
695        _last_run: Tick,
696    ) -> Self::Fetch<'w> {
697        state.contains(index)
698    }
699    //#[inline]
700    fn init_fetch_opt<'w>(
701        world: &'w World,
702        state: &'w Self::State,
703        index: ArchetypeIndex,
704        tick: Tick,
705        last_run: Tick,
706    ) -> Option<Self::Fetch<'w>> {
707        Some(Self::init_fetch(world, state, index, tick, last_run))
708    }
709    //#[inline(always)]
710    fn fetch<'w>(fetch: &Self::Fetch<'w>, _row: Row, _e: Entity) -> Self::Item<'w> {
711        *fetch
712    }
713}
714
715#[derive(Debug)]
716pub struct ComponentId<T: 'static>(pub ComponentIndex, PhantomData<T>);
717impl<T: 'static> FetchComponents for ComponentId<T> {
718    type Fetch<'w> = ComponentIndex;
719    type Item<'w> = ComponentIndex;
720    type ReadOnly = Self;
721    type State = ComponentIndex;
722
723    fn init_state(world: &mut World, _meta: &mut SystemMeta) -> Self::State {
724        world.init_component::<T>()
725    }
726
727    fn init_fetch<'w>(
728        _world: &'w World,
729        state: &'w Self::State,
730        _index: ArchetypeIndex,
731        _tick: Tick,
732        _last_run: Tick,
733    ) -> Self::Fetch<'w> {
734        *state
735    }
736    //#[inline]
737    fn init_fetch_opt<'w>(
738        world: &'w World,
739        state: &'w Self::State,
740        index: ArchetypeIndex,
741        tick: Tick,
742        last_run: Tick,
743    ) -> Option<Self::Fetch<'w>> {
744        Some(Self::init_fetch(world, state, index, tick, last_run))
745    }
746
747    fn fetch<'w>(fetch: &Self::Fetch<'w>, _row: Row, _e: Entity) -> Self::Item<'w> {
748        *fetch
749    }
750}
751
752#[derive(Debug)]
753pub struct ArchetypeName<'a>(pub &'a Cow<'static, str>, pub ArchetypeIndex, pub Row);
754impl FetchComponents for ArchetypeName<'_> {
755    type Fetch<'w> = (&'w Cow<'static, str>, ArchetypeIndex);
756    type Item<'w> = ArchetypeName<'w>;
757    type ReadOnly = Self;
758    type State = ();
759
760    fn init_state(_world: &mut World, _meta: &mut SystemMeta) -> Self::State {}
761
762    fn init_fetch<'w>(
763        world: &'w World,
764        _state: &'w Self::State,
765        index: ArchetypeIndex,
766        _tick: Tick,
767        _last_run: Tick,
768    ) -> Self::Fetch<'w> {
769        let archetype = world.get_archetype(index).unwrap();
770        (archetype.name(), archetype.index())
771    }
772
773    //#[inline]
774    fn init_fetch_opt<'w>(
775        world: &'w World,
776        state: &'w Self::State,
777        index: ArchetypeIndex,
778        tick: Tick,
779        last_run: Tick,
780    ) -> Option<Self::Fetch<'w>> {
781        Some(Self::init_fetch(world, state, index, tick, last_run))
782    }
783
784    fn fetch<'w>(fetch: &Self::Fetch<'w>, row: Row, _e: Entity) -> Self::Item<'w> {
785        ArchetypeName(fetch.0, fetch.1, row)
786    }
787}
788
789#[derive(Debug, Clone)]
790pub struct ColumnTick<'a> {
791    pub(crate) column: BlobRef<'a>,
792    pub(crate) tick: Tick,
793    pub(crate) last_run: Tick,
794}
795impl<'a> ColumnTick<'a> {
796    //#[inline(always)]
797    pub(crate) fn new(column: BlobRef<'a>, tick: Tick, last_run: Tick) -> Self {
798        Self {
799            column,
800            tick,
801            last_run,
802        }
803    }
804}
805
806#[derive(Debug)]
807pub struct TickRef<'a, T> {
808    pub(crate) c: ColumnTick<'a>,
809    pub(crate) row: Row,
810    pub(crate) e: Entity,
811    _p: PhantomData<T>,
812}
813
814impl<'a, T> TickRef<'a, T> {
815    //#[inline(always)]
816    pub fn new(c: &ColumnTick<'a>, row: Row, e: Entity) -> Self {
817        Self {
818            c: c.clone(),
819            row,
820            e,
821            _p: PhantomData,
822        }
823    }
824    //#[inline(always)]
825    pub fn entity(&self) -> Entity {
826        self.e
827    }
828    pub fn tick(&self) -> Tick {
829        self.c.column.get_tick_unchecked(self.row)
830    }
831    //#[inline(always)]
832    pub fn last_tick(&self) -> Tick {
833        self.c.last_run
834    }
835    //#[inline(always)]
836    pub fn is_changed(&self) -> bool {
837        self.c.column.get_tick_unchecked(self.row) > self.c.last_run
838    }
839}
840impl<'a, T: 'static> Deref for TickRef<'a, T> {
841    type Target = T;
842    //#[inline(always)]
843    fn deref(&self) -> &Self::Target {
844        self.c.column.get::<T>(self.row, self.e)
845    }
846}
847
848#[derive(Debug)]
849pub struct ValueRef<'a, T> {
850    pub(crate) value: &'a T,
851    pub(crate) tick: Tick,
852    pub(crate) last_run: Tick,
853}
854
855impl<'a, T> ValueRef<'a, T> {
856    //#[inline(always)]
857    pub fn new(value: &'a T, tick: Tick, last_run: Tick) -> Self {
858        Self {
859            value,
860            tick,
861            last_run,
862        }
863    }
864
865    pub fn tick(&self) -> Tick {
866        self.tick
867    }
868    //#[inline(always)]
869    pub fn last_tick(&self) -> Tick {
870        self.last_run
871    }
872    //#[inline(always)]
873    pub fn is_changed(&self) -> bool {
874        self.tick > self.last_run
875    }
876}
877impl<'a, T: 'static> Deref for ValueRef<'a, T> {
878    type Target = T;
879    //#[inline(always)]
880    fn deref(&self) -> &Self::Target {
881        self.value
882    }
883}
884
885#[derive(Debug)]
886pub struct Ticker<'a, T> {
887    pub(crate) c: ColumnTick<'a>,
888    pub(crate) e: Entity,
889    pub(crate) row: Row,
890    _p: PhantomData<T>,
891}
892
893impl<'a, T> Ticker<'a, T> {
894    pub fn new(c: &ColumnTick<'a>, e: Entity, row: Row) -> Self {
895        Self {
896            c: c.clone(),
897            e,
898            row,
899            _p: PhantomData,
900        }
901    }
902
903    pub fn entity(&self) -> Entity {
904        self.e
905    }
906
907    pub fn tick(&self) -> Tick {
908        self.c.column.get_tick_unchecked(self.row)
909    }
910
911    pub fn last_tick(&self) -> Tick {
912        self.c.last_run
913    }
914
915    pub fn is_changed(&self) -> bool {
916        self.c.column.get_tick_unchecked(self.row) > self.c.last_run
917    }
918}
919impl<'a, T: 'static> Deref for Ticker<'a, &'_ T> {
920    type Target = T;
921
922    fn deref(&self) -> &Self::Target {
923        self.c.column.get_unchecked::<T>(self.row)
924    }
925}
926
927impl<'a, T: 'static> Deref for Ticker<'a, &'_ mut T> {
928    type Target = T;
929
930    fn deref(&self) -> &Self::Target {
931        self.c.column.get_unchecked::<T>(self.row)
932    }
933}
934
935impl<'a, T: 'static> Ticker<'a, &'_ mut T> {
936    pub fn bypass_change_detection(&mut self) -> &mut T {
937        self.c.column.get_mut::<T>(self.row, self.e)
938    }
939
940    pub fn set_changed(&mut self) {
941        self.c.column.changed_tick(self.e, self.row, self.c.tick);
942    }
943}
944
945impl<'a, T: 'static> DerefMut for Ticker<'a, &'_ mut T> {
946    fn deref_mut(&mut self) -> &mut Self::Target {
947        self.c.column.changed_tick(self.e, self.row, self.c.tick);
948        self.c.column.get_mut::<T>(self.row, self.e)
949    }
950}
951
952/// Unique mutable borrow of an entity's component
953#[derive(Debug)]
954pub struct Mut<'a, T: 'static> {
955    pub(crate) c: ColumnTick<'a>,
956    pub(crate) e: Entity,
957    pub(crate) row: Row,
958    _p: PhantomData<T>,
959}
960impl<'a, T: Sized> Mut<'a, T> {
961    //#[inline(always)]
962    pub fn new(c: &ColumnTick<'a>, e: Entity, row: Row) -> Self {
963        Self {
964            c: c.clone(),
965            e,
966            row,
967            _p: PhantomData,
968        }
969    }
970    //#[inline(always)]
971    pub fn entity(&self) -> Entity {
972        self.e
973    }
974    pub fn tick(&self) -> Tick {
975        self.c.column.get_tick_unchecked(self.row)
976    }
977    //#[inline(always)]
978    pub fn last_tick(&self) -> Tick {
979        self.c.last_run
980    }
981    //#[inline(always)]
982    pub fn is_changed(&self) -> bool {
983        self.c.column.get_tick_unchecked(self.row) > self.c.last_run
984    }
985    pub fn bypass_change_detection(&mut self) -> &mut T {
986        self.c.column.get_mut::<T>(self.row, self.e)
987    }
988
989    pub fn set_changed(&mut self) {
990        self.c.column.changed_tick(self.e, self.row, self.c.tick);
991    }
992
993    pub fn into_inner(self) -> &'a mut T {
994        self.c.column.changed_tick(self.e, self.row, self.c.tick);
995        self.c.column.get_mut::<T>(self.row, self.e)
996    }
997}
998impl<'a, T: 'static> Deref for Mut<'a, T> {
999    type Target = T;
1000    //#[inline(always)]
1001    fn deref(&self) -> &Self::Target {
1002        self.c.column.get_unchecked::<T>(self.row)
1003    }
1004}
1005impl<'a, T: 'static> DerefMut for Mut<'a, T> {
1006    //#[inline(always)]
1007    fn deref_mut(&mut self) -> &mut Self::Target {
1008        // log::debug!("changed=================={:?}", std::any::type_name::<T>());
1009        self.c.column.changed_tick(self.e, self.row, self.c.tick);
1010        self.c.column.get_unchecked_mut::<T>(self.row)
1011    }
1012}
1013
1014macro_rules! impl_tuple_fetch {
1015    ($(($name: ident, $state: ident)),*) => {
1016        #[allow(non_snake_case)]
1017        #[allow(clippy::unused_unit)]
1018
1019        impl<$($name: FetchComponents),*> FetchComponents for ($($name,)*) {
1020            type Fetch<'w> = ($($name::Fetch<'w>,)*);
1021            type Item<'w> = ($($name::Item<'w>,)*);
1022            type ReadOnly = ($($name::ReadOnly,)*);
1023            type State = ($($name::State,)*);
1024
1025            fn init_state(_world: &mut World, _meta: &mut SystemMeta) -> Self::State {
1026                ($($name::init_state(_world, _meta),)*)
1027            }
1028            #[allow(clippy::unused_unit)]
1029            //#[inline(always)]
1030            fn init_fetch<'w>(
1031                _world: &'w World,
1032                _state: &'w Self::State,
1033                _index: ArchetypeIndex,
1034                _tick: Tick,
1035                _last_run: Tick,
1036                ) -> Self::Fetch<'w> {
1037                let ($($state,)*) = _state;
1038                ($($name::init_fetch(_world, $state, _index, _tick, _last_run),)*)
1039            }
1040
1041            //#[inline]
1042            fn init_fetch_opt<'w>(
1043                _world: &'w World,
1044                _state: &'w Self::State,
1045                _index: ArchetypeIndex,
1046                _tick: Tick,
1047                _last_run: Tick,
1048            ) -> Option<Self::Fetch<'w>> {
1049                let ($($state,)*) = _state;
1050                let r = ($(match $name::init_fetch_opt(_world, $state, _index, _tick, _last_run) {
1051                    Some(fetch) => fetch,
1052                    None => return None,
1053                },)*);
1054                Some(r)
1055            }
1056
1057            #[allow(clippy::unused_unit)]
1058            //#[inline(always)]
1059            fn fetch<'w>(
1060                _fetch: &Self::Fetch<'w>,
1061                _row: Row,
1062                _e: Entity,
1063            ) -> Self::Item<'w> {
1064                let ($($name,)*) = _fetch;
1065                ($($name::fetch($name, _row, _e),)*)
1066            }
1067        }
1068
1069    };
1070}
1071all_tuples!(impl_tuple_fetch, 0, 15, F, S);