Skip to content

Commit b7d784d

Browse files
committed
Bugfix State::set transition condition infinite loop (#4890)
# Objective - Fixes #4271 ## Solution - Check for a pending transition in addition to a scheduled operation. - I don't see a valid reason for updating the state unless both `scheduled` and `transition` are empty.
1 parent 5a09694 commit b7d784d

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

crates/bevy_ecs/src/schedule/state.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,14 @@ where
262262
}
263263

264264
/// Schedule a state change that replaces the active state with the given state.
265-
/// This will fail if there is a scheduled operation, or if the given `state` matches the
266-
/// current state
265+
/// This will fail if there is a scheduled operation, pending transition, or if the given
266+
/// `state` matches the current state
267267
pub fn set(&mut self, state: T) -> Result<(), StateError> {
268268
if self.stack.last().unwrap() == &state {
269269
return Err(StateError::AlreadyInState);
270270
}
271271

272-
if self.scheduled.is_some() {
272+
if self.scheduled.is_some() || self.transition.is_some() {
273273
return Err(StateError::StateAlreadyQueued);
274274
}
275275

@@ -289,14 +289,14 @@ where
289289
}
290290

291291
/// Schedule a state change that replaces the full stack with the given state.
292-
/// This will fail if there is a scheduled operation, or if the given `state` matches the
293-
/// current state
292+
/// This will fail if there is a scheduled operation, pending transition, or if the given
293+
/// `state` matches the current state
294294
pub fn replace(&mut self, state: T) -> Result<(), StateError> {
295295
if self.stack.last().unwrap() == &state {
296296
return Err(StateError::AlreadyInState);
297297
}
298298

299-
if self.scheduled.is_some() {
299+
if self.scheduled.is_some() || self.transition.is_some() {
300300
return Err(StateError::StateAlreadyQueued);
301301
}
302302

@@ -321,7 +321,7 @@ where
321321
return Err(StateError::AlreadyInState);
322322
}
323323

324-
if self.scheduled.is_some() {
324+
if self.scheduled.is_some() || self.transition.is_some() {
325325
return Err(StateError::StateAlreadyQueued);
326326
}
327327

@@ -342,7 +342,7 @@ where
342342

343343
/// Same as [`Self::set`], but does a pop operation instead of a set operation
344344
pub fn pop(&mut self) -> Result<(), StateError> {
345-
if self.scheduled.is_some() {
345+
if self.scheduled.is_some() || self.transition.is_some() {
346346
return Err(StateError::StateAlreadyQueued);
347347
}
348348

@@ -365,9 +365,9 @@ where
365365
}
366366

367367
/// Schedule a state change that restarts the active state.
368-
/// This will fail if there is a scheduled operation
368+
/// This will fail if there is a scheduled operation or a pending transition
369369
pub fn restart(&mut self) -> Result<(), StateError> {
370-
if self.scheduled.is_some() {
370+
if self.scheduled.is_some() || self.transition.is_some() {
371371
return Err(StateError::StateAlreadyQueued);
372372
}
373373

0 commit comments

Comments
 (0)