1use std::cell::{RefCell, RefMut};
2
3thread_local! {
4 static CURRENT_SYSTEM: std::cell::Cell<Option<&'static str>> = std::cell::Cell::new(None);
9}
10
11pub(crate) struct CurrentSystemGuard(Option<&'static str>);
15
16impl Drop for CurrentSystemGuard {
17 fn drop(&mut self) {
18 CURRENT_SYSTEM.with(|c| c.set(self.0));
19 }
20}
21
22pub(crate) fn set_current_system(name: &'static str) -> CurrentSystemGuard {
23 let previous = CURRENT_SYSTEM.with(|c| c.replace(Some(name)));
24 CurrentSystemGuard(previous)
25}
26
27fn current_system_suffix() -> String {
28 CURRENT_SYSTEM.with(|c| match c.get() {
29 Some(name) => format!(" (while running system `{name}`)"),
30 None => String::new(),
31 })
32}
33
34pub struct Resources {
40 pub(crate) resource_entity: hecs::Entity,
41 cmds: RefCell<hecs::CommandBuffer>,
42}
43
44impl Resources {
45 pub fn new(world: &mut hecs::World) -> Self {
47 Self {
48 resource_entity: world.spawn(()),
49 cmds: RefCell::new(hecs::CommandBuffer::default()),
50 }
51 }
52
53 pub fn insert_resource<T>(&mut self, world: &mut hecs::World, res: T)
55 where
56 T: hecs::Component,
57 {
58 world.insert_one(self.resource_entity, res).ok();
59 }
60
61 pub fn get_resource<'a, T>(&self, world: &'a hecs::World) -> hecs::Ref<'a, T>
63 where
64 T: hecs::Component,
65 {
66 world.get::<&T>(self.resource_entity).unwrap_or_else(|_| {
67 panic!(
68 "Resource not found: {}{}",
69 std::any::type_name::<T>(),
70 current_system_suffix()
71 )
72 })
73 }
74
75 pub fn get_resource_mut<'a, T>(&self, world: &'a hecs::World) -> hecs::RefMut<'a, T>
77 where
78 T: hecs::Component,
79 {
80 world.get::<&mut T>(self.resource_entity).unwrap_or_else(|_| {
81 panic!(
82 "Resource not found: {}{}",
83 std::any::type_name::<T>(),
84 current_system_suffix()
85 )
86 })
87 }
88
89 pub fn has_resource<T>(&self, world: &hecs::World) -> bool
91 where
92 T: hecs::Component,
93 {
94 if let Ok(_) = world.get::<&T>(self.resource_entity) {
95 return true;
96 }
97
98 false
99 }
100
101 pub fn get_command_buffer<'a>(&'a self) -> RefMut<'a, hecs::CommandBuffer> {
103 self.cmds.borrow_mut()
104 }
105
106 pub fn try_insert<T>(&mut self, world: &mut hecs::World, res: T) -> bool
110 where
111 T: hecs::Component,
112 {
113 if self.has_resource::<T>(world) {
114 return false;
115 }
116 world.insert_one(self.resource_entity, res).ok();
117 true
118 }
119}