FyroxEngine / Fyrox

3D and 2D game engine written in Rust
https://fyrox.rs
MIT License
7.61k stars 340 forks source link

request_sound_buffer: condvar wait not supported #406

Closed GOVYANSONG closed 1 year ago

GOVYANSONG commented 1 year ago

I run into this issue with sound manager. code snippet:

resource_manager .as_ref() .unwrap() .request_sound_buffer(path.as_ref())

Just want to confirm that it is not caused by block_on etc. in the codebase.

mrDIMAS commented 1 year ago

This is weird, is wasm example works for you? It should play music and it is played from a file that is request by the same code snippet as you provided.

GOVYANSONG commented 1 year ago

I will investigate more on my end. during meantime, just to record more details about the error:

Attempt to get reference to resource data while it is not loaded! Path is data/sounds/step.wav

Parking not supported on this platform', /home/mk8s/.cargo/registry/src/github.com-1ecc6299db9ec823/parking_lot_core-0.9.4/src/thread_parker/wasm.rs:26

mrDIMAS commented 1 year ago

Aha, you need to wait until the sound is fully loaded, every resource in the engine implements Future trait so it can be put into an async executor. Not sure what's the best way to do this since you cannot block current thread while waiting future result on wasm. It might be worth to create a simple sound manager that will take path to a sound, request it from the resource manager, spawn a task that will put loaded resources in to a queue. Then extract loaded sounds from the queue and play them.

Ideally, you shouldn't request any resources from scripts. You can just add a sound: Option<SoundBuffer> field to your script and then drag'n'drop a sound from Asset Browser on that field in the Inspector. This way the engine will handle resources for you. Or you can even create a SoundSource node, set it to Stopped state and set desired sound buffer the same way as described above, then in your game all you need to do is to play the sound.

GOVYANSONG commented 1 year ago

You can just add a sound: Option field to your script and then drag'n'drop a sound from Asset Browser on that field in the Inspector.

Did you mean soundbufferresource? also, my script is attached to a rigid body. I did add the option<> field in my script but after restarted the editor, when i check the properties of the rigid body, sound field is not shown for some reason.

Update

ok, the sound field is now populated with sound source e.g. a wav file. but attempt to playback with following code threw error:

let sound = SoundBuilder::new( BaseBuilder::new() .with_local_transform( TransformBuilder::new() .with_local_position(position) .build(), ), ) .with_buffer(self.sound.clone()) .with_status(Status::Playing) .with_play_once(true) .with_gain(0.6) .with_radius(1.0) .with_rolloff_factor(1.0) .build(&mut ctx.scene.graph);

    }

=============== thread 'main' panicked at 'assertion failed: self.buf_read_pos * (buffer.channel_count() as f64) <\n buffer.samples().len() as f64', /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/fyrox-sound/src/source.rs:469:13 stack backtrace: 0: rust_begin_unwind at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:584:5 1: core::panicking::panic_fmt at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/panicking.rs:142:14 2: core::panicking::panic at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/panicking.rs:48:5 3: fyrox_sound::source::SoundSource::set_playback_time at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/fyrox-sound/src/source.rs:469:13 4: fyrox_sound::source::SoundSourceBuilder::build at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/fyrox-sound/src/source.rs:848:9 5: fyrox::scene::sound::context::SoundContext::sync_to_sound at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/scene/sound/context.rs:302:19 6: fyrox::scene::graph::Graph::sync_native at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/scene/graph/mod.rs:916:13 7: fyrox::scene::graph::Graph::update at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/scene/graph/mod.rs:928:9 8: fyrox::scene::Scene::update at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/scene/mod.rs:570:9 9: fyrox::engine::Engine::pre_update at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/engine/mod.rs:706:13 10: fyrox::engine::Engine::update at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/engine/mod.rs:671:9 11: fyrox::engine::executor::Executor::run::{{closure}} at /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/6667eff/src/engine/executor.rs:175:25 12: winit::platform_impl::platform::sticky_exit_callback

mrDIMAS commented 1 year ago

I managed to reproduce the issue, I'll try to fix it today.

mrDIMAS commented 1 year ago

Alright, it is not an actual issue, it is just quirks of resource management of the engine. When you store a sound: Option<SoundBufferResource> in your script, the engine will save only path the resource on serialization step (when you save the scene in the editor). To restore actual resource from its "shallow" version you need to add this code in restore_resources method of your script:

resource_manager
            .state()
            .containers_mut()
            .sound_buffers
            .try_restore_optional_resource(&mut self.sound);

This is well known issue, and in future versions this method will be replaced with reflection-based solution so you don't need to re-fetch resources anymore.

mrDIMAS commented 1 year ago

I also fixed some other issues that I spotted along the way: missing property editor for sound status in Sound node, and wrong sync order of sound properties.

GOVYANSONG commented 1 year ago

I have integrated your code snippet above to look like below. I am getting a different error now:

ome/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/4b3093c/fyrox-resource/src/lib.rs:211:17 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace thread 'main' panicked at 'Attempt to get reference to resource data while it is not loaded! Path is data/sounds/metal.ogg', /home/mk8s/.cargo/git/checkouts/fyrox-3b28ccbadb9683b5/4b3093c/fyrox-resource/src/lib.rs:211:17 stack backtrace:

=========

// restore resource ctx.resource_manager .state() .containers_mut() .sound_buffers .try_restore_optional_resource(&mut self.sound);

        if self.sound.is_none() {return;}

        // play sound
        let sound = SoundBuilder::new(
            BaseBuilder::new()
            .with_local_transform(
            TransformBuilder::new()
            .with_local_position(position)
            .build(),
            ),
            )
            .with_buffer(self.sound.clone())
            .with_status(Status::Playing)
            .with_play_once(true)
            .with_gain(0.6)
            .with_radius(1.0)
            .with_rolloff_factor(1.0)
            .build(&mut ctx.scene.graph);
GOVYANSONG commented 1 year ago

Never mind, i misunderstood the line for restore_resources method. will verify now.

GOVYANSONG commented 1 year ago

@mrDIMAS the sound is now working as expected. thanks for the superb assistance.