diff --git a/src/callback.rs b/src/callback.rs index 416fcd7..54edd92 100644 --- a/src/callback.rs +++ b/src/callback.rs @@ -77,8 +77,16 @@ where let result = inner_system.run((), world); inner_system.apply_deferred(world); let mut runtime = world.get_resource_mut::().expect("No runtime resource"); - runtime - .with_engine_mut(move |engine| Out::into_runtime_value_with_engine(result, engine)) + + if R::is_current_thread() { + runtime.with_engine_mut(move |engine| { + Out::into_runtime_value_with_engine(result, engine) + }) + } else { + runtime.with_engine_thread_mut(move |engine| { + Out::into_runtime_value_with_engine(result, engine) + }) + } }; let system = IntoSystem::into_system(system_fn); CallbackSystem { @@ -110,9 +118,15 @@ macro_rules! impl_tuple { let result = inner_system.run(args, world); inner_system.apply_deferred(world); let mut runtime = world.get_resource_mut::().expect("No runtime resource"); - runtime.with_engine_mut(move |engine| { - Out::into_runtime_value_with_engine(result, engine) - }) + if RN::is_current_thread() { + runtime.with_engine_mut(move |engine| { + Out::into_runtime_value_with_engine(result, engine) + }) + } else { + runtime.with_engine_thread_mut(move |engine| { + Out::into_runtime_value_with_engine(result, engine) + }) + } }; let system = IntoSystem::into_system(system_fn); CallbackSystem { diff --git a/src/lib.rs b/src/lib.rs index a3d3364..95d4462 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -300,10 +300,12 @@ pub trait Runtime: Resource + Default { type Value: Send + Clone; type RawEngine; + fn is_current_thread() -> bool; + /// Provides mutable reference to raw scripting engine instance. /// Can be used to directly interact with an interpreter to use interfaces /// that bevy_scriptum does not provided adapters for. - fn with_engine_mut( + fn with_engine_thread_mut( &mut self, f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static, ) -> T; @@ -311,11 +313,21 @@ pub trait Runtime: Resource + Default { /// Provides immutable reference to raw scripting engine instance. /// Can be used to directly interact with an interpreter to use interfaces /// that bevy_scriptum does not provided adapters for. - fn with_engine( + fn with_engine_thread( &self, f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static, ) -> T; + /// Provides mutable reference to raw scripting engine instance. + /// Can be used to directly interact with an interpreter to use interfaces + /// that bevy_scriptum does not provided adapters for. + fn with_engine_mut(&mut self, f: impl FnOnce(&mut Self::RawEngine) -> T) -> T; + + /// Provides immutable reference to raw scripting engine instance. + /// Can be used to directly interact with an interpreter to use interfaces + /// that bevy_scriptum does not provided adapters for. + fn with_engine(&self, f: impl FnOnce(&Self::RawEngine) -> T) -> T; + fn eval( &self, script: &Self::ScriptAsset, diff --git a/src/runtimes/lua.rs b/src/runtimes/lua.rs index 5613ba2..0e55625 100644 --- a/src/runtimes/lua.rs +++ b/src/runtimes/lua.rs @@ -257,6 +257,24 @@ impl Runtime for LuaRuntime { let engine = self.engine.lock().unwrap(); f(&engine) } + + fn with_engine_thread_mut( + &mut self, + f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static, + ) -> T { + todo!() + } + + fn with_engine_thread( + &self, + f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static, + ) -> T { + todo!() + } + + fn is_current_thread() -> bool { + true + } } impl<'a, T: IntoLuaMulti<'a>> IntoRuntimeValueWithEngine<'a, T, LuaRuntime> for T { diff --git a/src/runtimes/rhai.rs b/src/runtimes/rhai.rs index c293364..c17e8b4 100644 --- a/src/runtimes/rhai.rs +++ b/src/runtimes/rhai.rs @@ -160,6 +160,24 @@ impl Runtime for RhaiRuntime { fn with_engine(&self, f: impl FnOnce(&Self::RawEngine) -> T) -> T { f(&self.engine) } + + fn with_engine_thread_mut( + &mut self, + f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static, + ) -> T { + todo!() + } + + fn with_engine_thread( + &self, + f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static, + ) -> T { + todo!() + } + + fn is_current_thread() -> bool { + true + } } impl Default for RhaiRuntime { diff --git a/src/runtimes/ruby.rs b/src/runtimes/ruby.rs index a7f851f..a0b34b5 100644 --- a/src/runtimes/ruby.rs +++ b/src/runtimes/ruby.rs @@ -136,7 +136,7 @@ impl Runtime for RubyRuntime { type RawEngine = magnus::Ruby; - fn with_engine_mut( + fn with_engine_thread_mut( &mut self, f: impl FnOnce(&mut Self::RawEngine) -> T + Send + 'static, ) -> T { @@ -146,7 +146,7 @@ impl Runtime for RubyRuntime { .execute_in(Box::new(move |mut ruby| f(&mut ruby))) } - fn with_engine( + fn with_engine_thread( &self, f: impl FnOnce(&Self::RawEngine) -> T + Send + 'static, ) -> T { @@ -156,6 +156,14 @@ impl Runtime for RubyRuntime { .execute_in(Box::new(move |ruby| f(&ruby))) } + fn with_engine_mut(&mut self, f: impl FnOnce(&mut Self::RawEngine) -> T) -> T { + unimplemented!(); + } + + fn with_engine(&self, f: impl FnOnce(&Self::RawEngine) -> T) -> T { + unimplemented!(); + } + fn eval( &self, script: &Self::ScriptAsset, @@ -256,6 +264,10 @@ impl Runtime for RubyRuntime { ) -> Result { todo!() } + + fn is_current_thread() -> bool { + false + } } pub mod prelude { diff --git a/tests/tests.rs b/tests/tests.rs index 13523aa..6e3da70 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -495,7 +495,7 @@ mod ruby_tests { fn assert_state_key_value_i64(world: &World, _entity_id: Entity, key: &str, value: i64) { let runtime = world.get_resource::().unwrap(); let key = key.to_string(); - runtime.with_engine(move |engine| { + runtime.with_engine_thread(move |engine| { let state: magnus::value::Value = engine.class_object().const_get("STATE").unwrap(); let res: i64 = state.funcall_public("[]", (key,)).unwrap(); assert_eq!(res, value)