use std::mem;
use slog::Logger;
use winapi::shared::winerror::E_FAIL;
use crate::com::ComObject;
use crate::ctsndcr::{ISoundCore, ParamInfo};
use crate::hresult::{check, Win32Error};
use crate::SoundCoreParameter;
pub struct SoundCoreParameterIterator {
target: ComObject<ISoundCore>,
logger: Logger,
context: u32,
feature_id: u32,
feature_description: String,
index: u32,
}
impl SoundCoreParameterIterator {
pub(crate) fn new(
target: ComObject<ISoundCore>,
logger: Logger,
context: u32,
feature_id: u32,
feature_description: String,
) -> Self {
Self {
target,
logger,
context,
feature_id,
feature_description,
index: 0,
}
}
}
impl Iterator for SoundCoreParameterIterator {
type Item = Result<SoundCoreParameter, Win32Error>;
fn next(&mut self) -> Option<Result<SoundCoreParameter, Win32Error>> {
unsafe {
let mut info: ParamInfo = mem::zeroed();
trace!(
self.logger,
"Fetching parameter .{}.{}[{}]...",
self.context,
self.feature_description,
self.index
);
match check(self.target.EnumParams(
self.context,
self.index,
self.feature_id,
&mut info,
)) {
Ok(_) => {}
Err(Win32Error { code, .. }) if code == E_FAIL => return None,
Err(error) => return Some(Err(error)),
};
trace!(
self.logger,
"Got parameter .{}.{}[{}] = {:?}",
self.context,
self.feature_description,
self.index,
info
);
self.index += 1;
match info.param.feature {
0 => None,
_ => Some(Ok(SoundCoreParameter::new(
self.target.clone(),
self.feature_description.clone(),
self.logger.clone(),
&info,
))),
}
}
}
}