Skip to content

Commit f53ad42

Browse files
committed
add: unload method for AudioAsset
1 parent 5453363 commit f53ad42

6 files changed

Lines changed: 67 additions & 31 deletions

File tree

Native/Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Native/uniasset/src/audio/audio_asset.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{
33
fmt::Display,
44
fs::File,
55
io::{self, Cursor, Read, Seek},
6+
ptr::null_mut,
67
sync::{
78
Arc,
89
atomic::{AtomicPtr, Ordering},
@@ -20,22 +21,25 @@ use crate::{
2021
thread::SyncUnsafeCell,
2122
};
2223

23-
pub struct AudioAsset(Box<Arc<SyncUnsafeCell<AudioAssetState>>>);
24+
pub struct AudioAsset(Box<Arc<(RwLock<SafeState>, SyncUnsafeCell<UnsafeState>)>>);
2425

2526
impl Default for AudioAsset {
2627
fn default() -> Self {
27-
Self(Box::new(Arc::new(AudioAssetState::default().into())))
28+
Self(Box::new(Arc::new((
29+
SafeState::default().into(),
30+
UnsafeState::default().into(),
31+
))))
2832
}
2933
}
3034

3135
impl AudioAsset {
32-
fn unsafe_mut_state<'a>(&'a self) -> &'a mut AudioAssetState {
33-
unsafe { &mut *self.0.get() }
36+
fn unsafe_state<'a>(&'a self) -> &'a mut UnsafeState {
37+
unsafe { &mut *self.0.1.get() }
3438
}
3539

3640
fn replace_decoder(&self, new_decoder: *mut AudioDecoderWrapper) {
3741
let old_ptr = self
38-
.unsafe_mut_state()
42+
.unsafe_state()
3943
.audio_decoder
4044
.swap(new_decoder, Ordering::Release);
4145

@@ -45,10 +49,7 @@ impl AudioAsset {
4549
}
4650

4751
fn load_decoder(&self) -> Result<*mut AudioDecoderWrapper, AudioOperationError> {
48-
let decoder_ptr = self
49-
.unsafe_mut_state()
50-
.audio_decoder
51-
.load(Ordering::Acquire);
52+
let decoder_ptr = self.unsafe_state().audio_decoder.load(Ordering::Acquire);
5253

5354
if decoder_ptr.is_null() {
5455
return Err(AudioOperationError::Unloaded);
@@ -57,7 +58,11 @@ impl AudioAsset {
5758
Ok(decoder_ptr)
5859
}
5960

60-
pub fn load_file(&self, path: impl AsRef<str>, sample_format: SampleFormat) -> Result<(), AudioOperationError> {
61+
pub fn load_file(
62+
&self,
63+
path: impl AsRef<str>,
64+
sample_format: SampleFormat,
65+
) -> Result<(), AudioOperationError> {
6166
self.load_io(File::open(path.as_ref())?, sample_format)
6267
}
6368

@@ -79,8 +84,7 @@ impl AudioAsset {
7984
}
8085

8186
let decoder = SymphoniaDecoder::from_io(stream, sample_format)?;
82-
let state = self.unsafe_mut_state();
83-
let _guard = state.lock.write();
87+
let mut state = self.0.0.write();
8488

8589
// Read audio info
8690
let info = AudioInfo {
@@ -98,9 +102,14 @@ impl AudioAsset {
98102
Ok(())
99103
}
100104

105+
pub fn unload(&self) {
106+
let mut state = self.0.0.write();
107+
state.audio_info = None;
108+
self.replace_decoder(null_mut());
109+
}
110+
101111
pub fn get_channel_count(&self) -> Result<u16, AudioOperationError> {
102-
let state = self.unsafe_mut_state();
103-
let _guard = state.lock.read();
112+
let state = self.0.0.read();
104113

105114
Ok(state
106115
.audio_info
@@ -110,8 +119,7 @@ impl AudioAsset {
110119
}
111120

112121
pub fn get_sample_count(&self) -> Result<u64, AudioOperationError> {
113-
let state = self.unsafe_mut_state();
114-
let _guard = state.lock.read();
122+
let state = self.0.0.read();
115123

116124
Ok(state
117125
.audio_info
@@ -121,8 +129,7 @@ impl AudioAsset {
121129
}
122130

123131
pub fn get_sample_rate(&self) -> Result<u32, AudioOperationError> {
124-
let state = self.unsafe_mut_state();
125-
let _guard = state.lock.read();
132+
let state = self.0.0.read();
126133

127134
Ok(state
128135
.audio_info
@@ -132,8 +139,7 @@ impl AudioAsset {
132139
}
133140

134141
pub fn get_frame_count(&self) -> Result<u64, AudioOperationError> {
135-
let state = self.unsafe_mut_state();
136-
let _guard = state.lock.read();
142+
let state = self.0.0.read();
137143

138144
Ok(state
139145
.audio_info
@@ -170,12 +176,15 @@ impl NativeHandleExts for AudioAsset {
170176
}
171177

172178
#[derive(Default)]
173-
struct AudioAssetState {
174-
lock: RwLock<()>,
175-
audio_info: Option<AudioInfo>,
179+
struct UnsafeState {
176180
audio_decoder: AtomicPtr<AudioDecoderWrapper>,
177181
}
178182

183+
#[derive(Default)]
184+
struct SafeState {
185+
audio_info: Option<AudioInfo>,
186+
}
187+
179188
struct AudioInfo {
180189
frame_count: u64,
181190
sample_count: u64,

Native/uniasset/src/ffi/audio.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,19 @@ pub unsafe extern "C" fn Uniasset_AudioAsset_LoadIO(
106106
}
107107
};
108108

109-
_ = failible_to_native(
110-
|| obj.load_io(unsafe { &mut *provider }, format),
111-
|| (),
112-
);
109+
_ = failible_to_native(|| obj.load_io(unsafe { &mut *provider }, format), || ());
113110

114111
std::mem::forget(obj);
115112
}
116113

114+
#[unsafe(no_mangle)]
115+
pub unsafe extern "C" fn Uniasset_AudioAsset_Unload(handle: NativeHandle) {
116+
clear_error();
117+
let obj = AudioAsset::from_handle(handle);
118+
obj.unload();
119+
std::mem::forget(obj);
120+
}
121+
117122
#[unsafe(no_mangle)]
118123
pub unsafe extern "C" fn Uniasset_AudioAsset_GetChannelCount(handle: NativeHandle) -> u16 {
119124
clear_error();
@@ -180,10 +185,7 @@ pub unsafe extern "C" fn Uniasset_AudioAsset_Read(
180185
}
181186

182187
#[unsafe(no_mangle)]
183-
pub unsafe extern "C" fn Uniasset_AudioAsset_Seek(
184-
handle: NativeHandle,
185-
position: i64,
186-
) {
188+
pub unsafe extern "C" fn Uniasset_AudioAsset_Seek(handle: NativeHandle, position: i64) {
187189
clear_error();
188190
let obj = AudioAsset::from_handle(handle);
189191
_ = failible_to_native(|| obj.seek(position), || ());

Unity/Uniasset/Audio/AudioAsset.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ public void Seek(long position)
5959
UnsafeHandle.Seek(position);
6060
}
6161

62+
public void Unload()
63+
{
64+
UnsafeHandle.Unload();
65+
}
66+
6267
public AudioClip ToAudioClip(string name = "created_from_uniasset", bool stream = true)
6368
{
6469
return AudioClip.Create(name, (int)(SampleCount / ChannelCount),

Unity/Uniasset/Unsafe/Interop.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ public static extern void Uniasset_ImageAsset_CropMultiple(
128128
[return: NativeTypeName("unsigned int")]
129129
public static extern uint Uniasset_AudioAsset_Read(void* self, [NativeTypeName("uint8_t *")] byte* buffer, [NativeTypeName("size_t")] ulong bufferSize, [NativeTypeName("unsigned int")] uint frameCount);
130130

131+
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
132+
public static extern void Uniasset_AudioAsset_Unload(void* self);
133+
131134
[DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
132135
public static extern void Uniasset_AudioAsset_Seek(void* self, [NativeTypeName("int64_t")] long position);
133136
}

Unity/Uniasset/Unsafe/UnsafeAudioAsset.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ public void Seek(long position)
106106
NativeException.ThrowIfNeeded();
107107
}
108108

109+
public void Unload()
110+
{
111+
Interop.Uniasset_AudioAsset_Unload(Instance);
112+
NativeException.ThrowIfNeeded();
113+
}
114+
109115
public void Destroy()
110116
{
111117
Interop.Uniasset_AudioAsset_Destory(Instance);

0 commit comments

Comments
 (0)