steel_core/world/tick_scheduler/
world.rs1use super::super::*;
2
3impl World {
4 pub fn schedule_block_tick(
11 &self,
12 pos: BlockPos,
13 block: BlockRef,
14 delay: i32,
15 priority: super::TickPriority,
16 ) {
17 let trigger_tick = self.game_time().wrapping_add(i64::from(delay));
18 let order = self.scheduled_ticks.next_sub_tick_order();
19 let chunk_pos = Self::chunk_pos_for_block(pos);
20 self.chunk_map.with_full_chunk(chunk_pos, |chunk| {
21 chunk.schedule_block_tick(pos, block, trigger_tick, priority, order);
22 });
23 }
24
25 pub fn schedule_block_tick_default(&self, pos: BlockPos, block: BlockRef, delay: i32) {
27 self.schedule_block_tick(pos, block, delay, super::TickPriority::Normal);
28 }
29
30 pub fn schedule_fluid_tick(
36 &self,
37 pos: BlockPos,
38 fluid: FluidRef,
39 delay: i32,
40 priority: super::TickPriority,
41 ) {
42 let trigger_tick = self.game_time().wrapping_add(i64::from(delay));
43 let order = self.scheduled_ticks.next_sub_tick_order();
44 let chunk_pos = Self::chunk_pos_for_block(pos);
45 self.chunk_map.with_full_chunk(chunk_pos, |chunk| {
46 chunk.schedule_fluid_tick(pos, fluid, trigger_tick, priority, order);
47 });
48 }
49
50 pub fn schedule_fluid_tick_default(&self, pos: BlockPos, fluid: FluidRef, delay: i32) {
52 self.schedule_fluid_tick(pos, fluid, delay, super::TickPriority::Normal);
53 }
54
55 pub fn has_scheduled_block_tick(&self, pos: BlockPos, block: BlockRef) -> bool {
62 let chunk_pos = Self::chunk_pos_for_block(pos);
63 self.chunk_map
64 .with_full_chunk(chunk_pos, |chunk| {
65 chunk
66 .has_scheduled_block_tick(pos, block)
67 .expect("Full chunk scheduled-tick ownership invariant failed")
68 })
69 .unwrap_or(false)
70 }
71
72 pub fn has_scheduled_fluid_tick(&self, pos: BlockPos, fluid: FluidRef) -> bool {
79 let chunk_pos = Self::chunk_pos_for_block(pos);
80 self.chunk_map
81 .with_full_chunk(chunk_pos, |chunk| {
82 chunk
83 .has_scheduled_fluid_tick(pos, fluid)
84 .expect("Full chunk scheduled-tick ownership invariant failed")
85 })
86 .unwrap_or(false)
87 }
88
89 pub(crate) fn register_full_chunk_ticks(
90 &self,
91 chunk: FullChunkRef<'_>,
92 ) -> Result<(), super::TickSchedulerError> {
93 self.scheduled_ticks.register_chunk(chunk)
94 }
95
96 pub(crate) fn unregister_full_chunk_ticks(&self, pos: ChunkPos) {
97 self.scheduled_ticks.unregister_chunk(pos);
98 }
99
100 #[cfg(test)]
101 pub(crate) fn has_registered_full_chunk_ticks(&self, pos: ChunkPos) -> bool {
102 self.scheduled_ticks.has_registered_chunk(pos)
103 }
104
105 #[cfg(test)]
106 pub(crate) fn has_indexed_scheduled_tick_head(&self, pos: ChunkPos) -> bool {
107 self.scheduled_ticks.has_indexed_head(pos)
108 }
109
110 pub(crate) fn schedule_block_tick_for_chunk(
111 &self,
112 chunk: FullChunkRef<'_>,
113 pos: BlockPos,
114 block: BlockRef,
115 trigger_tick: i64,
116 priority: super::TickPriority,
117 sub_tick_order: i64,
118 ) -> Result<bool, super::TickSchedulerError> {
119 self.scheduled_ticks.schedule_block(
120 chunk,
121 block,
122 pos,
123 trigger_tick,
124 priority,
125 sub_tick_order,
126 )
127 }
128
129 pub(crate) fn schedule_fluid_tick_for_chunk(
130 &self,
131 chunk: FullChunkRef<'_>,
132 pos: BlockPos,
133 fluid: FluidRef,
134 trigger_tick: i64,
135 priority: super::TickPriority,
136 sub_tick_order: i64,
137 ) -> Result<bool, super::TickSchedulerError> {
138 self.scheduled_ticks.schedule_fluid(
139 chunk,
140 fluid,
141 pos,
142 trigger_tick,
143 priority,
144 sub_tick_order,
145 )
146 }
147
148 pub(crate) fn unpack_scheduled_ticks(
149 &self,
150 pos: ChunkPos,
151 ) -> Result<(), super::TickSchedulerError> {
152 self.scheduled_ticks.unpack_chunk(pos, self.game_time())
153 }
154
155 pub(crate) fn reconcile_active_scheduled_tick_chunks<I>(
156 &self,
157 active_chunks: I,
158 ) -> Result<(), super::TickSchedulerError>
159 where
160 I: Iterator<Item = ChunkPos> + Clone,
161 {
162 self.scheduled_ticks.reconcile_active_chunks(active_chunks)
163 }
164
165 pub(crate) fn begin_scheduled_tick_phase(
166 &self,
167 current_tick: i64,
168 max_ticks: usize,
169 ) -> super::ScheduledTickBatch<BlockRef> {
170 self.scheduled_ticks.begin_tick(current_tick, max_ticks)
171 }
172
173 pub(crate) fn collect_scheduled_fluid_tick_batch(
174 &self,
175 current_tick: i64,
176 max_ticks: usize,
177 ) -> super::ScheduledTickBatch<FluidRef> {
178 self.scheduled_ticks
179 .collect_fluid_ticks(current_tick, max_ticks)
180 }
181
182 pub fn will_tick_block_this_tick(&self, pos: BlockPos, block: BlockRef) -> bool {
188 let batch = self
189 .scheduled_block_ticks_this_tick
190 .lock()
191 .as_ref()
192 .cloned();
193 batch.is_some_and(|batch| batch.contains(pos, block))
194 }
195
196 pub fn will_tick_fluid_this_tick(&self, pos: BlockPos, fluid: FluidRef) -> bool {
198 let batch = self
199 .scheduled_fluid_ticks_this_tick
200 .lock()
201 .as_ref()
202 .cloned();
203 batch.is_some_and(|batch| batch.contains(pos, fluid))
204 }
205
206 pub(crate) fn begin_scheduled_block_tick_batch(
207 &self,
208 ticks: Vec<super::BlockTick>,
209 ) -> Arc<super::ScheduledTickRunBatch<BlockRef>> {
210 let batch = Arc::new(super::ScheduledTickRunBatch::new(ticks));
211 let mut current = self.scheduled_block_ticks_this_tick.lock();
212 assert!(
213 current.is_none(),
214 "scheduled block-tick batch was already active"
215 );
216 *current = Some(Arc::clone(&batch));
217 batch
218 }
219
220 pub(crate) fn end_scheduled_block_tick_batch(
221 &self,
222 batch: &Arc<super::ScheduledTickRunBatch<BlockRef>>,
223 ) {
224 let removed = {
225 let mut current = self.scheduled_block_ticks_this_tick.lock();
226 assert!(
227 current
228 .as_ref()
229 .is_some_and(|current| Arc::ptr_eq(current, batch)),
230 "scheduled block-tick batch identity changed during execution"
231 );
232 current.take()
233 };
234 drop(removed);
235 }
236
237 pub(crate) fn begin_scheduled_fluid_tick_batch(
238 &self,
239 ticks: Vec<super::FluidTick>,
240 ) -> Arc<super::ScheduledTickRunBatch<FluidRef>> {
241 let batch = Arc::new(super::ScheduledTickRunBatch::new(ticks));
242 let mut current = self.scheduled_fluid_ticks_this_tick.lock();
243 assert!(
244 current.is_none(),
245 "scheduled fluid-tick batch was already active"
246 );
247 *current = Some(Arc::clone(&batch));
248 batch
249 }
250
251 pub(crate) fn end_scheduled_fluid_tick_batch(
252 &self,
253 batch: &Arc<super::ScheduledTickRunBatch<FluidRef>>,
254 ) {
255 let removed = {
256 let mut current = self.scheduled_fluid_ticks_this_tick.lock();
257 assert!(
258 current
259 .as_ref()
260 .is_some_and(|current| Arc::ptr_eq(current, batch)),
261 "scheduled fluid-tick batch identity changed during execution"
262 );
263 current.take()
264 };
265 drop(removed);
266 }
267}