How can i get the reference to App or World #5133
-
What problem does this solve or what need does it fill?I wan't to insert But, when I get the ref to for example #[derive(Clone)]
pub struct SeekerEnv<'a> {
pub world: Arc<Mutex<&'a mut World>>,
}
unsafe impl Sync for SeekerEnv<'_> {}
unsafe impl Send for SeekerEnv<'_> {}
pub struct SeekerEnvInstance {
pub instance: Instance,
}
impl FromWorld for SeekerEnv<'static> {
fn from_world(world: &mut World) -> Self {
let seeker_env;
unsafe {
let ref_world = &mut *(world as *mut World);
seeker_env = SeekerEnv {
world: Arc::new(Mutex::new(ref_world))
}
}
let script_path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/crates/wrst/target/wasm32-wasi/release/welcome.wasm"
);
info!("{}", script_path);
let store = Store::default();
let module = match Module::from_file(&store, script_path) {
Ok(m) => m,
Err(err) => {
dbg!(err);
panic!();
// return ;
},
};
let mut wasi_env = WasiState::new("seeker").finalize().unwrap();
let mut import_object = wasi_env.import_object(&module).unwrap();
let store = Store::default();
let mut _seeker_env = Arc::new(Mutex::new(seeker_env.clone()));
let mut seeker_ns: Exports = namespace! {
"create_window" => Function::new_native_with_env(&store, _seeker_env.clone(), create_window),
"add_sprite" => Function::new_native_with_env(&store, _seeker_env.clone(), add_sprite),
"query_entity_ids" => Function::new_native_with_env(&store, _seeker_env.clone(), query_entity_ids),
"create_entity_id" => Function::new_native_with_env(&store, _seeker_env.clone(), create_entity_id),
};
import_object.register_namespace("seeker", seeker_ns);
let instance = Instance::new(&module, &import_object).unwrap();
world.insert_resource(SeekerEnvInstance {
instance
});
seeker_env
}
}
But when I get the ref to World in system, The world id is 3, and I can not spawn entity in my app by this world ref. So I need to add a exclusive_system to fixed it fn setup_world(
world: &mut World
) {
unsafe {
let ref_world = &mut *(world as *mut World);
let mut env = world.get_resource_mut::<SeekerEnv>().unwrap();
*(env.world.lock().unwrap()) = ref_world;
}
} After this exclusive_system, the world id is 0. and i can sapwn an entity by this world. Is there some better solution. And I did not known how to get the ref to |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Hi! We use Github Discussions for questions here; I'm going to convert this to a discussion and hopefully someone can help you over there :) |
Beta Was this translation helpful? Give feedback.
-
You can't keep a What you can do is fill the fn run_scripts_system(world: &mut World) {
let seeker_env = ...;
std::mem::swap(world, &mut seeker_env.world);
// run scripts
std::mem::swap(&mut seeker_env.world, world);
} (it can't be exactly this because of the arc and mutex, but the point is to have the environment own the world for just the duration of execution) I do something similar here in my experimentation with JS-Scripting via V8 and In a different experiment with lua I did use an pub fn with_world(
world: &mut World,
...
) -> Result<(), mlua::Error> {
let w = std::mem::take(world);
let shared_world = Arc::new(RwLock::new(w));
// insert shared world into lua and run script
lua.gc_collect()?;
*world = Arc::try_unwrap(shared_world)
.expect("there are dangling references to the world left!")
.into_inner()
.expect("the world lock was poisoned");
res
} Also, I suggest to use |
Beta Was this translation helpful? Give feedback.
You can't keep a
&mut World
alive in your environment for longer than the duration of one exclusive system, because rust rules require you to never, ever have two aliasing (=alive at the same time) mutable references to the same variable.What you can do is fill the
SeekerEnv
with an empty dummyWorld::new()
when creating it.When you want to actually run the wasm script with access to the world, you can do something like this:
(it can't be exactly this because of the arc and mutex, but the point is to have…