1use super::{
2 query::{EntQueryMut, Query, QueryMut, ResQuery, ResQueryMut},
3 request::{
4 Request, RequestInfo, RequestKey, Response, StoreRequestInfo, SystemBuffer, RINFO_STOR,
5 },
6};
7use crate::{
8 ds::{ATypeId, ListPos, ManagedMutPtr, NonNullExt, SetList, SimpleVecPool},
9 ecs::EcsError,
10 util::{macros::debug_format, Or},
11};
12use std::{
13 any::{self, Any},
14 borrow,
15 collections::{HashMap, HashSet},
16 fmt,
17 hash::{self, BuildHasher},
18 marker::PhantomData,
19 mem,
20 ops::{Deref, DerefMut},
21 ptr::NonNull,
22 sync::Arc,
23};
24
25use SystemState::*;
26
27#[allow(private_interfaces, private_bounds)]
115pub trait System: Send + 'static {
116 type Request: Request;
117
118 fn run(&mut self, resp: Response<'_, Self::Request>);
120
121 #[doc(hidden)]
122 #[allow(unused_variables)]
123 fn run_private(&mut self, sid: SystemId, buf: ManagedMutPtr<SystemBuffer>) {}
124
125 #[allow(unused_variables)]
129 fn on_transition(&mut self, from: SystemState, to: SystemState) {}
130
131 fn name() -> &'static str {
133 any::type_name::<Self>()
134 }
135
136 #[doc(hidden)]
137 fn key() -> SystemKey {
138 SystemKey::of::<Self>()
139 }
140
141 #[doc(hidden)]
142 fn into_data(self) -> SystemData
143 where
144 Self: Sized + 'static,
145 {
146 let boxed = Box::new(self);
147 let ptr = unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) };
149 Self::_create_data(ptr, SystemFlags::OWNED_SET)
150 }
151
152 #[doc(hidden)]
153 unsafe fn create_data(ptr: NonNull<dyn Invoke + Send>) -> SystemData
154 where
155 Self: Sized + 'static,
156 {
157 Self::_create_data(ptr, SystemFlags::OWNED_RESET)
158 }
159
160 #[doc(hidden)]
161 fn _create_data(invoker: NonNull<dyn Invoke + Send>, flags: SystemFlags) -> SystemData {
162 let mut stor = RINFO_STOR.lock().unwrap();
163 let rinfo = Arc::clone(Self::Request::get_info_from(&mut *stor));
164 drop(stor);
165
166 SystemData {
167 id: SystemId::dummy(),
168 flags,
169 invoker,
170 info: Arc::new(SystemInfo::new(
171 Self::name(),
172 Self::key(),
173 Self::Request::key(),
174 rinfo,
175 )),
176 }
177 }
178}
179
180#[derive(Debug)]
208pub(crate) struct SystemGroup<S> {
209 cur_id: SystemId,
211
212 active: SystemCycle<S>,
214
215 inactive: HashSet<SystemData, S>,
217
218 dead: Vec<SystemData>,
220
221 poisoned: Vec<PoisonedSystem>,
223
224 volatile: HashSet<SystemId, S>,
227
228 lifetime: SystemLifetime<S>,
230}
231
232impl<S> SystemGroup<S>
233where
234 S: BuildHasher + Default,
235{
236 pub(crate) fn new(gi: u16) -> Self {
237 let dummy = ().into_data();
238
239 Self {
240 cur_id: SystemId::new(gi, 1),
241 active: SystemCycle::new(dummy),
242 inactive: HashSet::default(),
243 dead: Vec::new(),
244 poisoned: Vec::new(),
245 volatile: HashSet::default(),
246 lifetime: SystemLifetime::new(),
247 }
248 }
249
250 pub(crate) fn clear(&mut self) {
260 let mut sids = Vec::with_capacity(self.len_active() + self.len_inactive());
262 for sdata in self.active.values() {
263 sids.push(sdata.id());
264 }
265 while let Some(sid) = sids.pop() {
266 self.inactivate(&sid).unwrap();
267 }
268
269 for sdata in self.inactive.iter() {
271 sids.push(sdata.id());
272 }
273 while let Some(sid) = sids.pop() {
274 self.unregister(&sid).unwrap();
275 }
276
277 self.drain_dead();
279 self.drain_poisoned();
280 }
281
282 pub(crate) fn len_active(&self) -> usize {
283 self.active.len()
284 }
285
286 pub(crate) fn len_inactive(&self) -> usize {
287 self.inactive.len()
288 }
289
290 pub(crate) fn get_active_mut(&mut self) -> &mut SystemCycle<S> {
292 &mut self.active
293 }
294
295 pub(crate) fn is_active(&self, sid: &SystemId) -> bool {
296 self.active.contains(sid)
297 }
298
299 pub(crate) fn contains(&self, sid: &SystemId) -> bool {
302 self.contains_active(sid) || self.contains_inactive(sid)
303 }
304
305 pub(crate) fn contains_active(&self, sid: &SystemId) -> bool {
307 self.active.contains(sid)
308 }
309
310 pub(crate) fn contains_inactive(&self, sid: &SystemId) -> bool {
312 self.inactive.contains(sid)
313 }
314
315 pub(crate) fn get_active(&self, sid: &SystemId) -> Option<&SystemData> {
317 self.active.get(sid)
318 }
319
320 pub(crate) fn next_system_id(&self) -> SystemId {
322 self.cur_id
323 }
324
325 pub(crate) fn register(
340 &mut self,
341 sdata: SystemData,
342 volatile: bool,
343 ) -> Result<(), EcsError<SystemData>> {
344 if sdata.id() != self.cur_id {
346 let reason = debug_format!("invalid system id");
347 return Err(EcsError::Unknown(reason, sdata));
348 }
349 if self.contains(&sdata.id()) {
350 let reason = debug_format!("duplicated system id");
351 return Err(EcsError::Unknown(reason, sdata));
352 }
353
354 let sid = sdata.id();
356 self.cur_id.add_system_index(1);
357
358 let is_new = self.inactive.insert(sdata);
360 debug_assert!(is_new);
361
362 if volatile {
364 let is_new = self.volatile.insert(sid);
365 debug_assert!(is_new);
366 }
367 Ok(())
368 }
369
370 pub(crate) fn activate(
382 &mut self,
383 target: &SystemId,
384 at: InsertPos,
385 live: Tick,
386 ) -> Result<(), EcsError> {
387 if let InsertPos::After(after) = at {
389 if !self.is_active(&after) {
390 let reason =
392 debug_format!("cannot activate a system due to invalid insert position");
393 return Err(EcsError::UnknownSystem(reason, ()));
394 }
395 }
396
397 if let Some(mut sdata) = self.inactive.take(target) {
398 debug_assert_eq!(sdata.id(), *target);
399
400 sdata.as_invoker_mut().on_transition(Inactive, Active);
401 let must_true = self.active.insert(sdata, at);
402 debug_assert!(must_true);
403
404 self.lifetime.register(*target, live);
406 Ok(())
407 } else {
408 let reason = debug_format!("system activation is allowed for inactive systems only");
409 Err(EcsError::UnknownSystem(reason, ()))
410 }
411 }
412
413 pub(crate) fn unregister(&mut self, sid: &SystemId) -> Result<(), EcsError> {
423 if let Some(mut sdata) = self.inactive.take(sid) {
424 sdata.as_invoker_mut().on_transition(Inactive, Dead);
425 self.dead.push(sdata);
426 Ok(())
427 } else {
428 let reason = debug_format!("tried to unregister a not inactive system");
429 Err(EcsError::UnknownSystem(reason, ()))
430 }
431 }
432
433 pub(crate) fn poison(
439 &mut self,
440 sid: &SystemId,
441 payload: Box<dyn Any + Send>,
442 ) -> Result<(), EcsError<Box<dyn Any + Send>>> {
443 let sdata = if let Some(mut sdata) = self.active.remove(sid) {
444 sdata.as_invoker_mut().on_transition(Active, Poisoned);
445 sdata
446 } else if let Some(mut sdata) = self.inactive.take(sid) {
447 sdata.as_invoker_mut().on_transition(Inactive, Poisoned);
448 sdata
449 } else {
450 let reason = debug_format!("tried to poison a not (in)active system");
451 return Err(EcsError::UnknownSystem(reason, payload));
452 };
453 let poisoned = PoisonedSystem::from_system_data(sdata, payload);
454 self.poisoned.push(poisoned);
455 Ok(())
456 }
457
458 pub(crate) fn inactivate(&mut self, sid: &SystemId) -> Result<(), EcsError> {
473 let Self {
474 active,
475 inactive,
476 dead,
477 volatile,
478 ..
479 } = self;
480
481 Self::_inactivate(sid, active, inactive, dead, volatile)
482 }
483
484 fn _inactivate(
485 sid: &SystemId,
486 active: &mut SystemCycle<S>,
487 inactive: &mut HashSet<SystemData, S>,
488 dead: &mut Vec<SystemData>,
489 volatile: &mut HashSet<SystemId, S>,
490 ) -> Result<(), EcsError> {
491 if inactive.contains(sid) {
492 Ok(())
493 } else if let Some(mut sdata) = active.remove(sid) {
494 if volatile.contains(sid) {
495 sdata.as_invoker_mut().on_transition(Active, Dead);
496 dead.push(sdata);
497 } else {
498 sdata.as_invoker_mut().on_transition(Active, Inactive);
499 inactive.insert(sdata);
500 }
501 Ok(())
502 } else {
503 let reason = debug_format!("tried to inactivate a not (in)active system");
504 Err(EcsError::UnknownSystem(reason, ()))
505 }
506 }
507
508 pub(crate) fn drain_dead(&mut self) -> std::vec::Drain<'_, SystemData> {
510 for sdata in self.dead.iter() {
511 self.volatile.remove(&sdata.id());
512 }
513 self.dead.drain(..)
514 }
515
516 pub(crate) fn drain_poisoned(&mut self) -> std::vec::Drain<'_, PoisonedSystem> {
518 for poisoned in self.poisoned.iter() {
519 self.volatile.remove(&poisoned.id());
520 }
521 self.poisoned.drain(..)
522 }
523
524 pub(crate) fn tick(&mut self) {
525 let Self {
526 active,
527 inactive,
528 dead,
529 volatile,
530 lifetime,
531 ..
532 } = self;
533
534 if let Some(expired_sids) = lifetime.tick() {
535 while let Some(sid) = expired_sids.pop() {
536 let _ = Self::_inactivate(&sid, active, inactive, dead, volatile);
537 }
538 }
539 }
540}
541
542#[derive(Debug)]
563pub enum SystemState {
564 Active,
565 Inactive,
566 Dead,
567 Poisoned,
568}
569
570#[derive(Debug)]
572#[repr(transparent)]
573pub(crate) struct SystemCycle<S>(SetList<SystemId, SystemData, S>);
574
575impl<S> SystemCycle<S>
576where
577 S: BuildHasher + Default,
578{
579 pub(crate) fn new(dummy: SystemData) -> Self {
581 Self(SetList::new(dummy))
582 }
583
584 pub(crate) fn len(&self) -> usize {
585 self.0.len()
586 }
587
588 pub(crate) fn contains(&self, sid: &SystemId) -> bool {
589 self.0.contains_key(sid)
590 }
591
592 pub(crate) fn insert(&mut self, sdata: SystemData, at: InsertPos) -> bool {
593 match at {
594 InsertPos::After(after) => self.0.insert(sdata.id(), sdata, &after),
595 InsertPos::Back => self.0.push_back(sdata.id(), sdata),
596 InsertPos::Front => self.0.push_front(sdata.id(), sdata),
597 }
598 }
599
600 pub(crate) fn remove(&mut self, sid: &SystemId) -> Option<SystemData> {
601 self.0.remove(sid)
602 }
603
604 pub(crate) fn iter_begin(&mut self) -> SystemCycleIter<'_, S> {
605 SystemCycleIter::new(&mut self.0)
606 }
607}
608
609impl<S> Deref for SystemCycle<S> {
610 type Target = SetList<SystemId, SystemData, S>;
611
612 fn deref(&self) -> &Self::Target {
613 &self.0
614 }
615}
616
617impl<S> DerefMut for SystemCycle<S> {
618 fn deref_mut(&mut self) -> &mut Self::Target {
619 &mut self.0
620 }
621}
622
623#[derive(Debug)]
624#[repr(transparent)]
625pub(crate) struct SystemCycleIter<'a, S> {
626 raw: RawSystemCycleIter<S>,
627
628 _marker: PhantomData<&'a mut ()>,
629}
630
631impl<S> SystemCycleIter<'_, S> {
632 pub(crate) fn into_raw(self) -> RawSystemCycleIter<S> {
633 self.raw
634 }
635
636 pub(crate) unsafe fn from_raw(raw: RawSystemCycleIter<S>) -> Self {
637 Self {
638 raw,
639 _marker: PhantomData,
640 }
641 }
642
643 pub(crate) fn position(&self) -> ListPos {
645 self.raw.position()
646 }
647}
648
649impl<'a, S> SystemCycleIter<'a, S>
650where
651 S: BuildHasher,
652{
653 pub(crate) fn new(systems: &'a mut SetList<SystemId, SystemData, S>) -> Self {
654 Self {
655 raw: RawSystemCycleIter::new(systems),
656 _marker: PhantomData,
657 }
658 }
659
660 pub(crate) fn get(&mut self) -> Option<&mut SystemData> {
662 unsafe { self.raw.get() }
664 }
665
666 pub(crate) fn get_at(&mut self, pos: ListPos) -> Option<&mut SystemData> {
668 unsafe { self.raw.get_at(pos) }
670 }
671}
672
673#[derive(Debug)]
674pub(crate) struct RawSystemCycleIter<S> {
675 systems: NonNull<SetList<SystemId, SystemData, S>>,
677
678 cur_pos: ListPos,
680}
681
682impl<S> RawSystemCycleIter<S> {
683 pub(crate) fn position(&self) -> ListPos {
685 self.cur_pos
686 }
687}
688
689impl<S> RawSystemCycleIter<S>
690where
691 S: BuildHasher,
692{
693 pub(crate) fn new(systems: &mut SetList<SystemId, SystemData, S>) -> Self {
694 let cur_pos = systems.first_position();
695 let systems = unsafe { NonNull::new_unchecked(systems as *mut _) };
697
698 Self { systems, cur_pos }
699 }
700
701 pub(crate) unsafe fn next(&mut self) {
703 let systems = unsafe { self.systems.as_ref() };
704 if let Some((next, _sdata)) = systems.iter_next(self.cur_pos) {
705 self.cur_pos = next;
706 }
707 }
708
709 pub(crate) unsafe fn get(&mut self) -> Option<&mut SystemData> {
711 unsafe { self.get_at(self.cur_pos) }
712 }
713
714 pub(crate) unsafe fn get_at(&mut self, pos: ListPos) -> Option<&mut SystemData> {
716 let systems = unsafe { self.systems.as_mut() };
717 systems.iter_next_mut(pos).map(|(_, sdata)| sdata)
718 }
719}
720
721impl<S> Clone for RawSystemCycleIter<S> {
722 fn clone(&self) -> Self {
723 *self
724 }
725}
726
727impl<S> Copy for RawSystemCycleIter<S> {}
728
729#[derive(Debug, Clone, Copy)]
738pub enum InsertPos {
739 Back,
740 Front,
741 After(SystemId),
742}
743
744#[derive(Debug)]
745struct SystemLifetime<S> {
746 tick: Tick,
748
749 lives: HashMap<Tick, usize, S>,
751
752 pool: SimpleVecPool<SystemId>,
754}
755
756impl<S> SystemLifetime<S>
757where
758 S: BuildHasher + Default,
759{
760 fn new() -> Self {
761 Self {
762 tick: 0,
763 lives: HashMap::default(),
764 pool: SimpleVecPool::new(),
765 }
766 }
767
768 fn register(&mut self, sid: SystemId, live: Tick) {
769 debug_assert!(live > 0);
770
771 let end = self.tick.saturating_add(live);
772 let index = *self.lives.entry(end).or_insert(self.pool.request());
773 let vec = self.pool.get(index);
774 vec.push(sid);
775 }
776
777 fn tick(&mut self) -> Option<&mut Vec<SystemId>> {
778 self.tick += 1;
779 self.lives.remove(&self.tick).map(|index| {
780 self.pool.release(index);
781 self.pool.get(index)
782 })
783 }
784}
785
786impl System for () {
788 type Request = ();
789 fn run(&mut self, _resp: Response<Self::Request>) {}
790}
791
792pub(crate) type SystemKey = ATypeId<SystemKey_>;
794pub(crate) struct SystemKey_;
795
796#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
798pub struct SystemId {
799 group_index: u16,
800 system_index: u16,
801}
802
803impl SystemId {
804 const DUMMY: Self = Self {
805 group_index: u16::MAX,
806 system_index: u16::MAX,
807 };
808 const MAX: u16 = u16::MAX - 1;
809
810 pub(crate) const fn dummy() -> Self {
811 Self::DUMMY
812 }
813
814 pub(crate) fn is_dummy(&self) -> bool {
815 self == &Self::dummy()
816 }
817
818 pub(crate) const fn new(group_index: u16, system_index: u16) -> Self {
819 Self {
820 group_index,
821 system_index,
822 }
823 }
824
825 pub(crate) const fn group_index(&self) -> u16 {
826 self.group_index
827 }
828
829 pub(crate) const fn max_system_index() -> u16 {
830 Self::MAX
831 }
832
833 pub(crate) fn add_system_index(&mut self, by: u16) {
834 assert!(
835 self.system_index < Self::max_system_index(),
836 "number of systems exceeded its limit {}",
837 Self::max_system_index() - 1
838 );
839 self.system_index += by;
840 }
841}
842
843impl Default for SystemId {
844 fn default() -> Self {
845 Self::dummy()
846 }
847}
848
849impl fmt::Display for SystemId {
850 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
851 write!(f, "({}, {})", self.group_index, self.system_index)
852 }
853}
854
855pub(crate) struct SystemData {
862 id: SystemId,
864
865 flags: SystemFlags,
866
867 invoker: NonNull<(dyn Invoke + Send)>,
869
870 info: Arc<SystemInfo>,
877}
878
879unsafe impl Send for SystemData {}
885unsafe impl Sync for SystemData {}
886
887impl SystemData {
888 pub(crate) fn try_into_any(self) -> Result<Box<dyn Any + Send>, Self> {
889 if self.flags.is_owned() {
890 let boxed = unsafe { Box::from_raw(self.invoker.as_ptr()) };
892
893 mem::forget(self);
895
896 Ok(boxed.into_any())
897 } else {
898 Err(self)
899 }
900 }
901}
902
903impl Drop for SystemData {
904 fn drop(&mut self) {
905 if self.flags.is_owned() {
907 unsafe { drop(Box::from_raw(self.invoker.as_ptr())) };
909 }
910 }
911}
912
913impl fmt::Debug for SystemData {
914 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
915 f.debug_struct("SystemData")
916 .field("id", &self.id)
917 .field("flags", &self.flags)
918 .field("info", &self.info)
919 .finish_non_exhaustive()
920 }
921}
922
923impl hash::Hash for SystemData {
924 fn hash<H: hash::Hasher>(&self, state: &mut H) {
925 self.id.hash(state);
926 }
927}
928
929impl PartialEq for SystemData {
930 fn eq(&self, other: &Self) -> bool {
931 self.id == other.id
932 }
933}
934
935impl Eq for SystemData {}
936
937impl borrow::Borrow<SystemId> for SystemData {
938 fn borrow(&self) -> &SystemId {
939 &self.id
940 }
941}
942
943impl SystemData {
944 pub(crate) const fn id(&self) -> SystemId {
945 self.id
946 }
947
948 pub(crate) const fn flags(&self) -> SystemFlags {
949 self.flags
950 }
951
952 pub(crate) fn set_id(&mut self, sid: SystemId) {
953 self.id = sid;
954 }
955
956 pub(crate) fn union_flags(&mut self, sflags: SystemFlags) {
957 self.flags |= sflags;
958 }
959
960 pub(crate) fn info(&self) -> Arc<SystemInfo> {
961 Arc::clone(&self.info)
962 }
963
964 pub(crate) fn get_request_info(&self) -> &Arc<RequestInfo> {
965 unsafe { self.info.rinfo.as_ref().unwrap_unchecked() }
967 }
968
969 pub(crate) fn as_invoker_mut(&mut self) -> &mut (dyn Invoke + Send) {
970 unsafe { self.invoker.as_mut() }
974 }
975
976 pub(crate) unsafe fn task_ptr(&mut self) -> ManagedMutPtr<dyn Invoke + Send> {
977 unsafe {
978 let ptr = self.invoker.as_ptr();
979 let ptr = NonNullExt::new_unchecked(ptr);
980 ManagedMutPtr::new(ptr)
981 }
982 }
983}
984
985#[derive(Debug)]
986pub struct PoisonedSystem {
987 id: SystemId,
988 name: &'static str,
989 data: Option<Box<dyn Any + Send>>,
990 err_payload: Box<dyn Any + Send>,
991}
992
993impl PoisonedSystem {
994 const fn new(
995 id: SystemId,
996 name: &'static str,
997 data: Option<Box<dyn Any + Send>>,
998 err_payload: Box<dyn Any + Send>,
999 ) -> Self {
1000 Self {
1001 id,
1002 name,
1003 data,
1004 err_payload,
1005 }
1006 }
1007
1008 fn from_system_data(sdata: SystemData, err_payload: Box<dyn Any + Send>) -> Self {
1009 let id = sdata.id;
1010 let name = sdata.info().name;
1011 let data = sdata.try_into_any().ok();
1012 Self::new(id, name, data, err_payload)
1013 }
1014
1015 pub fn id(&self) -> SystemId {
1016 self.id
1017 }
1018
1019 pub fn name(&self) -> &'static str {
1020 self.name
1021 }
1022
1023 pub fn take_data(&mut self) -> Option<Box<dyn Any + Send>> {
1024 self.data.take()
1025 }
1026
1027 pub fn into_error_payload(self) -> Box<dyn Any + Send> {
1028 self.err_payload
1029 }
1030}
1031
1032#[derive(Clone, Copy)]
1033pub(crate) struct SystemFlags(u32);
1034
1035bitflags::bitflags! {
1036 impl SystemFlags: u32 {
1037 const DEDI_SET = 1;
1038 const DEDI_RESET = 1 << 1;
1039
1040 const PRIVATE_SET = 1 << 2;
1041 const PRIVATE_RESET = 1 << 3;
1042
1043 const OWNED_SET = 1 << 4;
1044 const OWNED_RESET = 1 << 5;
1045 }
1046}
1047
1048impl SystemFlags {
1049 pub(crate) const fn is_dedi(&self) -> bool {
1050 debug_assert!(!self.is_dedi_empty());
1051
1052 self.intersects(Self::DEDI_SET)
1053 }
1054
1055 pub(crate) const fn is_dedi_empty(&self) -> bool {
1056 !self.intersects(Self::DEDI_SET.union(Self::DEDI_RESET))
1057 }
1058
1059 pub(crate) const fn is_private(&self) -> bool {
1060 debug_assert!(!self.is_private_empty());
1061
1062 self.intersects(Self::PRIVATE_SET)
1063 }
1064
1065 pub(crate) const fn is_private_empty(&self) -> bool {
1066 !self.intersects(Self::PRIVATE_SET.union(Self::PRIVATE_RESET))
1067 }
1068
1069 pub(crate) const fn is_owned(&self) -> bool {
1070 debug_assert!(!self.is_owned_empty());
1071
1072 self.intersects(Self::OWNED_SET)
1073 }
1074
1075 pub(crate) const fn is_owned_empty(&self) -> bool {
1076 !self.intersects(Self::OWNED_SET.union(Self::OWNED_RESET))
1077 }
1078}
1079
1080impl fmt::Debug for SystemFlags {
1081 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1082 let dedi = if !self.is_dedi_empty() {
1083 if self.is_dedi() {
1084 "DEDI"
1085 } else {
1086 "NON-DEDI"
1087 }
1088 } else {
1089 "DEDI?"
1090 };
1091
1092 let private = if !self.is_private_empty() {
1093 if self.is_private() {
1094 "PRIVATE"
1095 } else {
1096 "NON-PRIVATE"
1097 }
1098 } else {
1099 "PRIVATE?"
1100 };
1101
1102 let owned = if !self.is_owned_empty() {
1103 if self.is_owned() {
1104 "OWNED"
1105 } else {
1106 "NON-OWNED"
1107 }
1108 } else {
1109 "OWNED?"
1110 };
1111
1112 f.debug_tuple("SystemFlags")
1113 .field(&[dedi, private, owned].join(" | "))
1114 .finish()
1115 }
1116}
1117
1118pub(crate) struct SystemInfo {
1119 name: &'static str,
1121
1122 _skey: SystemKey,
1123
1124 rkey: RequestKey,
1127
1128 rinfo: Option<Arc<RequestInfo>>,
1133}
1134
1135impl SystemInfo {
1136 const fn new(
1137 name: &'static str,
1138 skey: SystemKey,
1139 rkey: RequestKey,
1140 rinfo: Arc<RequestInfo>,
1141 ) -> Self {
1142 Self {
1143 name,
1144 _skey: skey,
1145 rkey,
1146 rinfo: Some(rinfo),
1147 }
1148 }
1149
1150 pub(crate) fn get_request_info(&self) -> &RequestInfo {
1151 unsafe { self.rinfo.as_ref().unwrap_unchecked() }
1153 }
1154}
1155
1156impl fmt::Debug for SystemInfo {
1157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1158 f.debug_struct("SystemInfo")
1159 .field("name", &self.name)
1160 .finish_non_exhaustive()
1161 }
1162}
1163
1164impl Drop for SystemInfo {
1165 fn drop(&mut self) {
1166 drop(self.rinfo.take());
1168 let mut stor = RINFO_STOR.lock().unwrap();
1169 stor.remove(&self.rkey);
1170 }
1171}
1172
1173pub struct SystemDesc<Sys> {
1175 pub(crate) sys: Or<Sys, SystemData>,
1178
1179 pub(crate) private: bool,
1182
1183 pub group_index: u16,
1185
1186 pub volatile: bool,
1191
1192 pub activation: (Tick, InsertPos),
1202}
1203
1204impl<Sys> fmt::Debug for SystemDesc<Sys> {
1205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1206 f.debug_struct("SystemDesc")
1207 .field("private", &self.private)
1208 .field("group_index", &self.group_index)
1209 .field("volatile", &self.volatile)
1210 .field("activation", &self.activation)
1211 .finish_non_exhaustive()
1212 }
1213}
1214
1215impl<Sys> SystemDesc<Sys>
1216where
1217 Sys: System,
1218{
1219 pub fn with_system<T, OutSys>(self, sys: T) -> SystemDesc<OutSys>
1220 where
1221 T: Into<SystemBond<OutSys>>,
1222 OutSys: System,
1223 {
1224 let sys: SystemBond<OutSys> = sys.into();
1225
1226 SystemDesc::<OutSys> {
1227 sys: Or::A(sys.into_inner()),
1228 private: self.private,
1229 group_index: self.group_index,
1230 volatile: self.volatile,
1231 activation: self.activation,
1232 }
1233 }
1234
1235 pub fn with_once<T, Req, F>(self, sys: T) -> SystemDesc<FnOnceSystem<Req, F>>
1236 where
1237 T: Into<FnOnceSystem<Req, F>>,
1238 FnOnceSystem<Req, F>: System,
1239 {
1240 let activation = if self.activation.0 > 0 {
1241 (1, self.activation.1)
1242 } else {
1243 self.activation
1244 };
1245
1246 SystemDesc::<FnOnceSystem<Req, F>> {
1247 sys: Or::A(sys.into()),
1248 private: self.private,
1249 group_index: self.group_index,
1250 volatile: self.volatile,
1251 activation,
1252 }
1253 }
1254
1255 pub fn with_group_index(self, index: u16) -> Self {
1256 Self {
1257 group_index: index,
1258 ..self
1259 }
1260 }
1261
1262 pub fn with_volatile(self, volatile: bool) -> Self {
1263 Self { volatile, ..self }
1264 }
1265
1266 pub fn with_activation(self, live: Tick, insert_at: InsertPos) -> Self {
1267 Self {
1268 activation: (live, insert_at),
1269 ..self
1270 }
1271 }
1272
1273 pub fn take_system(self) -> Sys {
1275 match self.sys {
1276 Or::A(sys) => sys,
1277 Or::B(_sdata) => panic!(),
1278 }
1279 }
1280
1281 pub(crate) fn with_data(self, sdata: SystemData) -> SystemDesc<()> {
1282 SystemDesc::<()> {
1283 sys: Or::B(sdata),
1284 private: self.private,
1285 group_index: self.group_index,
1286 volatile: self.volatile,
1287 activation: self.activation,
1288 }
1289 }
1290
1291 pub(crate) fn with_private(self, private: bool) -> Self {
1292 Self { private, ..self }
1293 }
1294}
1295
1296impl SystemDesc<()> {
1297 pub const fn new() -> Self {
1298 Self {
1299 sys: Or::A(()),
1300 private: false,
1301 group_index: 0,
1302 volatile: true,
1303 activation: (Tick::MAX, InsertPos::Back),
1304 }
1305 }
1306}
1307
1308impl Default for SystemDesc<()> {
1309 fn default() -> Self {
1310 Self::new()
1311 }
1312}
1313
1314impl<T: System> From<T> for SystemDesc<T> {
1315 fn from(value: T) -> Self {
1316 SystemDesc::new().with_system(value)
1317 }
1318}
1319
1320pub(crate) trait Invoke {
1322 fn invoke(&mut self, buf: &mut SystemBuffer);
1323 fn invoke_private(&mut self, sid: SystemId, buf: ManagedMutPtr<SystemBuffer>);
1324 fn on_transition(&mut self, from: SystemState, to: SystemState);
1325 fn into_any(self: Box<Self>) -> Box<dyn Any + Send>;
1326}
1327
1328impl<S: System> Invoke for S {
1329 fn invoke(&mut self, buf: &mut SystemBuffer) {
1330 self.run(Response::new(buf));
1331 }
1332
1333 fn invoke_private(&mut self, sid: SystemId, buf: ManagedMutPtr<SystemBuffer>) {
1334 self.run_private(sid, buf);
1335 }
1336
1337 fn on_transition(&mut self, from: SystemState, to: SystemState) {
1338 self.on_transition(from, to);
1339 }
1340
1341 fn into_any(self: Box<Self>) -> Box<dyn Any + Send> {
1342 self
1343 }
1344}
1345
1346#[repr(transparent)]
1359pub struct FnSystem<Req, F> {
1360 run: F,
1361 _marker: PhantomData<Req>,
1362}
1363
1364unsafe impl<Req, F: Send> Send for FnSystem<Req, F> {}
1365
1366impl<Req, F> fmt::Debug for FnSystem<Req, F>
1367where
1368 Self: System,
1369{
1370 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1371 write!(f, "{}", Self::name())
1372 }
1373}
1374
1375#[repr(transparent)]
1388pub struct FnOnceSystem<Req, F> {
1389 run: Option<F>,
1390 _marker: PhantomData<Req>,
1391}
1392
1393unsafe impl<Req, F: Send> Send for FnOnceSystem<Req, F> {}
1394
1395impl<Req, F> fmt::Debug for FnOnceSystem<Req, F>
1396where
1397 Self: System,
1398{
1399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1400 write!(f, "{}", Self::name())
1401 }
1402}
1403
1404#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1410pub struct Ph;
1411
1412#[rustfmt::skip]
1413mod impl_for_fn_system {
1414 use super::*;
1415 use crate::ecs::sys::query::{Read, Write, ResRead, ResWrite, EntWrite};
1416
1417 macro_rules! _impl {
1418 (
1419 $req_with_placeholder:ty,
1420 $req_with_tuple:ty
1421 $(,r=$r:ident)?
1422 $(,w=$w:ident)?
1423 $(,rr=$rr:ident)?
1424 $(,rw=$rw:ident)?
1425 $(,ew=$ew:ident)?
1426 ) => {
1427 impl<F $(,$r)? $(,$w)? $(,$rr)? $(,$rw)? $(,$ew)?>
1429 From<F> for
1430 FnSystem<$req_with_placeholder, F>
1431 where
1432 F: FnMut(
1433 $(Read<$r>,)?
1434 $(Write<$w>,)?
1435 $(ResRead<$rr>,)?
1436 $(ResWrite<$rw>,)?
1437 $(EntWrite<$ew>,)?
1438 ),
1439 $($r: Query,)?
1440 $($w: QueryMut,)?
1441 $($rr: ResQuery,)?
1442 $($rw: ResQueryMut,)?
1443 $($ew: EntQueryMut,)?
1444 {
1445 fn from(value: F) -> Self {
1446 Self {
1447 run: value,
1448 _marker: PhantomData,
1449 }
1450 }
1451 }
1452
1453 impl<F $(,$r)? $(,$w)? $(,$rr)? $(,$rw)? $(,$ew)?>
1455 From<F> for
1456 FnOnceSystem<$req_with_placeholder, F>
1457 where
1458 F: FnOnce(
1459 $(Read<$r>,)?
1460 $(Write<$w>,)?
1461 $(ResRead<$rr>,)?
1462 $(ResWrite<$rw>,)?
1463 $(EntWrite<$ew>,)?
1464 ),
1465 $($r: Query,)?
1466 $($w: QueryMut,)?
1467 $($rr: ResQuery,)?
1468 $($rw: ResQueryMut,)?
1469 $($ew: EntQueryMut,)?
1470 {
1471 fn from(value: F) -> Self {
1472 Self {
1473 run: Some(value),
1474 _marker: PhantomData,
1475 }
1476 }
1477 }
1478
1479 impl<F $(,$r)? $(,$w)? $(,$rr)? $(,$rw)? $(,$ew)?>
1481 System for
1482 FnSystem<$req_with_placeholder, F>
1483 where
1484 F: FnMut(
1485 $(Read<$r>,)?
1486 $(Write<$w>,)?
1487 $(ResRead<$rr>,)?
1488 $(ResWrite<$rw>,)?
1489 $(EntWrite<$ew>,)?
1490 ) + Send + 'static,
1491 $($r: Query,)?
1492 $($w: QueryMut,)?
1493 $($rr: ResQuery,)?
1494 $($rw: ResQueryMut,)?
1495 $($ew: EntQueryMut,)?
1496 {
1497 type Request = $req_with_tuple;
1498
1499 fn run(&mut self, _resp: Response<Self::Request>) {
1500 (self.run)(
1501 $(Read::<'_, $r>(_resp.read),)?
1502 $(Write::<'_, $w>(_resp.write),)?
1503 $(ResRead::<'_, $rr>(_resp.res_read),)?
1504 $(ResWrite::<'_, $rw>(_resp.res_write),)?
1505 $(EntWrite::<$ew>(_resp.ent_write),)?
1506 )
1507 }
1508
1509 fn name() -> &'static str {
1510 std::any::type_name::<F>()
1511 }
1512 }
1513
1514 impl<F $(,$r)? $(,$w)? $(,$rr)? $(,$rw)? $(,$ew)?>
1516 System for
1517 FnOnceSystem<$req_with_placeholder, F>
1518 where
1519 F: FnOnce(
1520 $(Read<$r>,)?
1521 $(Write<$w>,)?
1522 $(ResRead<$rr>,)?
1523 $(ResWrite<$rw>,)?
1524 $(EntWrite<$ew>,)?
1525 ) + Send + 'static,
1526 $($r: Query,)?
1527 $($w: QueryMut,)?
1528 $($rr: ResQuery,)?
1529 $($rw: ResQueryMut,)?
1530 $($ew: EntQueryMut,)?
1531 {
1532 type Request = $req_with_tuple;
1533
1534 fn run(&mut self, _resp: Response<Self::Request>) {
1535 if let Some(run) = self.run.take() {
1536 (run)(
1537 $(Read::<'_, $r>(_resp.read),)?
1538 $(Write::<'_, $w>(_resp.write),)?
1539 $(ResRead::<'_, $rr>(_resp.res_read),)?
1540 $(ResWrite::<'_, $rw>(_resp.res_write),)?
1541 $(EntWrite::<$ew>(_resp.ent_write),)?
1542 )
1543 } else {
1544 panic!(
1545 "unable to call `{}` twice, which implements FnOnce",
1546 std::any::type_name::<F>()
1547 );
1548 }
1549 }
1550
1551 fn name() -> &'static str {
1552 std::any::type_name::<F>()
1553 }
1554 }
1555
1556 impl<F $(,$r)? $(,$w)? $(,$rr)? $(,$rw)? $(,$ew)?>
1558 From<F> for
1559 SystemBond<FnSystem<$req_with_placeholder, F>>
1560 where
1561 F: FnMut(
1562 $(Read<$r>,)?
1563 $(Write<$w>,)?
1564 $(ResRead<$rr>,)?
1565 $(ResWrite<$rw>,)?
1566 $(EntWrite<$ew>,)?
1567 ),
1568 $($r: Query,)?
1569 $($w: QueryMut,)?
1570 $($rr: ResQuery,)?
1571 $($rw: ResQueryMut,)?
1572 $($ew: EntQueryMut,)?
1573 {
1574 fn from(value: F) -> Self {
1575 Self(value.into())
1576 }
1577 }
1578
1579 impl<F $(,$r)? $(,$w)? $(,$rr)? $(,$rw)? $(,$ew)?>
1581 From<F> for
1582 SystemDesc<FnSystem<$req_with_placeholder, F>>
1583 where
1584 F: FnMut(
1585 $(Read<$r>,)?
1586 $(Write<$w>,)?
1587 $(ResRead<$rr>,)?
1588 $(ResWrite<$rw>,)?
1589 $(EntWrite<$ew>,)?
1590 ) + Send + 'static,
1591 $($r: Query,)?
1592 $($w: QueryMut,)?
1593 $($rr: ResQuery,)?
1594 $($rw: ResQueryMut,)?
1595 $($ew: EntQueryMut,)?
1596 {
1597 fn from(value: F) -> Self {
1598 SystemDesc::new().with_system(value)
1599 }
1600 }
1601 };
1602 }
1603
1604 #[allow(non_camel_case_types)]
1605 type o = Ph; _impl!((o , o , o , o , o ), ((), (), (), (), ()));
1608 _impl!((R, o , o , o , o ), (R, (), (), (), ()), r=R);
1609 _impl!((o , W, o , o , o ), ((), W, (), (), ()), w=W);
1610 _impl!((R, W, o , o , o ), (R, W, (), (), ()), r=R, w=W);
1611 _impl!((o , o , RR, o , o ), ((), (), RR, (), ()), rr=RR);
1612 _impl!((R, o , RR, o , o ), (R, (), RR, (), ()), r=R, rr=RR);
1613 _impl!((o , W, RR, o , o ), ((), W, RR, (), ()), w=W, rr=RR);
1614 _impl!((R, W, RR, o , o ), (R, W, RR, (), ()), r=R, w=W, rr=RR);
1615 _impl!((o , o , o , RW, o ), ((), (), (), RW, ()), rw=RW);
1616 _impl!((R, o , o , RW, o ), (R, (), (), RW, ()), r=R, rw=RW);
1617 _impl!((o , W, o , RW, o ), ((), W, (), RW, ()), w=W, rw=RW);
1618 _impl!((R, W, o , RW, o ), (R, W, (), RW, ()), r=R, w=W, rw=RW);
1619 _impl!((o , o , RR, RW, o ), ((), (), RR, RW, ()), rr=RR, rw=RW);
1620 _impl!((R, o , RR, RW, o ), (R, (), RR, RW, ()), r=R, rr=RR, rw=RW);
1621 _impl!((o , W, RR, RW, o ), ((), W, RR, RW, ()), w=W, rr=RR, rw=RW);
1622 _impl!((R, W, RR, RW, o ), (R, W, RR, RW, ()), r=R, w=W, rr=RR, rw=RW);
1623
1624 _impl!((o , o , o , o , EW), ((), (), (), (), EW), ew=EW);
1625 _impl!((R, o , o , o , EW), (R, (), (), (), EW), r=R, ew=EW);
1626 _impl!((o , W, o , o , EW), ((), W, (), (), EW), w=W, ew=EW);
1627 _impl!((R, W, o , o , EW), (R, W, (), (), EW), r=R, w=W, ew=EW);
1628 _impl!((o , o , RR, o , EW), ((), (), RR, (), EW), rr=RR, ew=EW);
1629 _impl!((R, o , RR, o , EW), (R, (), RR, (), EW), r=R, rr=RR, ew=EW);
1630 _impl!((o , W, RR, o , EW), ((), W, RR, (), EW), w=W, rr=RR, ew=EW);
1631 _impl!((R, W, RR, o , EW), (R, W, RR, (), EW), r=R, w=W, rr=RR, ew=EW);
1632 _impl!((o , o , o , RW, EW), ((), (), (), RW, EW), rw=RW, ew=EW);
1633 _impl!((R, o , o , RW, EW), (R, (), (), RW, EW), r=R, rw=RW, ew=EW);
1634 _impl!((o , W, o , RW, EW), ((), W, (), RW, EW), w=W, rw=RW, ew=EW);
1635 _impl!((R, W, o , RW, EW), (R, W, (), RW, EW), r=R, w=W, rw=RW, ew=EW);
1636 _impl!((o , o , RR, RW, EW), ((), (), RR, RW, EW), rr=RR, rw=RW, ew=EW);
1637 _impl!((R, o , RR, RW, EW), (R, (), RR, RW, EW), r=R, rr=RR, rw=RW, ew=EW);
1638 _impl!((o , W, RR, RW, EW), ((), W, RR, RW, EW), w=W, rr=RR, rw=RW, ew=EW);
1639 _impl!((R, W, RR, RW, EW), (R, W, RR, RW, EW), r=R, w=W, rr=RR, rw=RW, ew=EW);
1640}
1641
1642#[derive(Debug)]
1659#[repr(transparent)]
1660pub struct SystemBond<S>(S);
1661
1662impl<S> SystemBond<S> {
1663 pub(crate) fn into_inner(self) -> S {
1664 self.0
1665 }
1666}
1667
1668impl<S: System> From<S> for SystemBond<S> {
1669 fn from(value: S) -> Self {
1670 Self(value)
1671 }
1672}
1673
1674pub type Tick = u64;
1678
1679#[cfg(test)]
1680mod tests {
1681 use super::*;
1682
1683 #[test]
1684 fn test_systemgroup_unregister_volatile() {
1685 let mut sgroup = SystemGroup::<hash::RandomState>::new(0);
1686
1687 let mut sdata: SystemData = ().into_data();
1690 let sid = sgroup.next_system_id();
1691 sdata.id = sid;
1692 sgroup.register(sdata, true).unwrap();
1693 validate_len(&sgroup, 0, 1, 1);
1694
1695 sgroup.unregister(&sid).unwrap();
1698 sgroup.drain_dead();
1699 validate_len(&sgroup, 0, 0, 0);
1700 }
1701
1702 #[test]
1703 fn test_systemgroup_mixed_operations() {
1704 let mut sgroup = SystemGroup::<hash::RandomState>::new(0);
1705
1706 let mut sdata: SystemData = ().into_data();
1709 let sid_a = sgroup.next_system_id();
1710 sdata.id = sid_a;
1711 sgroup.register(sdata, false).unwrap();
1712 validate_len(&sgroup, 0, 1, 0);
1713
1714 sgroup.activate(&sid_a, InsertPos::Back, 1).unwrap();
1717 validate_len(&sgroup, 1, 0, 0);
1718
1719 let mut sdata: SystemData = ().into_data();
1722 let sid_b = sgroup.next_system_id();
1723 sdata.id = sid_b;
1724 sgroup.register(sdata, true).unwrap();
1725 validate_len(&sgroup, 1, 1, 1);
1726
1727 sgroup.activate(&sid_b, InsertPos::Back, 2).unwrap();
1730 validate_len(&sgroup, 2, 0, 1);
1731
1732 sgroup.tick();
1735 sgroup.drain_dead();
1736 validate_len(&sgroup, 1, 1, 1);
1737
1738 sgroup.tick();
1741 sgroup.drain_dead();
1742 validate_len(&sgroup, 0, 1, 0);
1743
1744 sgroup.unregister(&sid_a).unwrap();
1747 sgroup.drain_dead();
1748 validate_len(&sgroup, 0, 0, 0);
1749 }
1750
1751 fn validate_len<S>(sgroup: &SystemGroup<S>, act: usize, inact: usize, vol: usize)
1752 where
1753 S: BuildHasher + Default,
1754 {
1755 assert_eq!(sgroup.active.len(), act);
1756 assert_eq!(sgroup.inactive.len(), inact);
1757 assert_eq!(sgroup.volatile.len(), vol);
1758 }
1759}