From 4a7cdfab80d9df76a995853e40a30f994010b64b Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Sat, 24 Feb 2024 14:30:09 -0500 Subject: [PATCH] ecs: fix executing deferred fn system arguments --- lyra-ecs/src/system/fn_sys.rs | 3 ++- lyra-ecs/src/system/graph.rs | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lyra-ecs/src/system/fn_sys.rs b/lyra-ecs/src/system/fn_sys.rs index 856ce16..fd7ac5c 100644 --- a/lyra-ecs/src/system/fn_sys.rs +++ b/lyra-ecs/src/system/fn_sys.rs @@ -80,12 +80,13 @@ macro_rules! impl_fn_system_tuple { fn execute_deferred(&mut self, world: NonNull) -> anyhow::Result<()> { let state = self.arg_state.as_mut().expect("Somehow there was no state"); + state.reverse(); $( let arg_state_box = state.pop() .expect("Missing expected arg state"); let arg_state = *arg_state_box.downcast::<$name::State>() - .unwrap(); + .expect("Somehow the state cannot be downcasted from boxed Any"); $name::apply_deferred(arg_state, world); )+ diff --git a/lyra-ecs/src/system/graph.rs b/lyra-ecs/src/system/graph.rs index 18ef23a..40ac0cc 100644 --- a/lyra-ecs/src/system/graph.rs +++ b/lyra-ecs/src/system/graph.rs @@ -2,7 +2,7 @@ use std::{collections::{HashMap, VecDeque, HashSet}, ptr::NonNull}; use super::System; -use crate::world::World; +use crate::{world::World, CommandQueue, Commands}; #[derive(thiserror::Error, Debug)] pub enum GraphExecutorError { @@ -58,7 +58,7 @@ impl GraphExecutor { } /// Executes the systems in the graph - pub fn execute(&mut self, world_ptr: NonNull, stop_on_error: bool) -> Result, GraphExecutorError> { + pub fn execute(&mut self, mut world_ptr: NonNull, stop_on_error: bool) -> Result, GraphExecutorError> { let mut stack = VecDeque::new(); let mut visited = HashSet::new(); @@ -91,6 +91,25 @@ impl GraphExecutor { possible_errors.push(e); unimplemented!("Cannot resume topological execution from error"); // TODO: resume topological execution from error } + + let world = unsafe { world_ptr.as_mut() }; + if let Some(mut queue) = world.try_get_resource_mut::() { + // Safety: Commands only borrows world.entities when adding commands + let world = unsafe { world_ptr.as_mut() }; + let mut commands = Commands::new(&mut queue, world); + + let world = unsafe { world_ptr.as_mut() }; + if let Err(e) = commands.execute(world) + .map_err(|e| GraphExecutorError::Command(e)) { + + if stop_on_error { + return Err(e); + } + + possible_errors.push(e); + unimplemented!("Cannot resume topological execution from error"); // TODO: resume topological execution from error + } + } } Ok(possible_errors)