Skip to content

Commit

Permalink
Merge pull request #1333 from autumnontape/driver-iterator
Browse files Browse the repository at this point in the history
implement `FusedIterator`, `DoubleEndedIterator`, and `nth[_back]` for driver iterators
  • Loading branch information
Cobrand authored Sep 18, 2023
2 parents 5b4d40f + c00e2a0 commit dfc982c
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 18 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ when upgrading from a version of rust-sdl2 to another.

[PR #1332](https://github.com/Rust-SDL2/rust-sdl2/pull/1332) Fix `size_hint` implementations for `{audio,video,render}::DriverIterator`

[PR #1333](https://github.com/Rust-SDL2/rust-sdl2/pull/1333) Implement `FusedIterator`, `DoubleEndedIterator`, `and nth[_back]` for `{audio,video,render}::DriverIterator`

[PR #1337](https://github.com/Rust-SDL2/rust-sdl2/pull/1337) Fix "Cannot initialize Sdl from more than one thread" for tests / CI

### v0.35.2
Expand Down
60 changes: 54 additions & 6 deletions src/sdl2/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,18 @@ pub struct DriverIterator {
index: i32,
}

// panics if SDL_GetAudioDriver returns a null pointer,
// which only happens if index is outside the range
// 0..SDL_GetNumAudioDrivers()
fn get_audio_driver(index: i32) -> &'static str {
unsafe {
let buf = sys::SDL_GetAudioDriver(index);
assert!(!buf.is_null());

CStr::from_ptr(buf as *const _).to_str().unwrap()
}
}

impl Iterator for DriverIterator {
type Item = &'static str;

Expand All @@ -360,13 +372,10 @@ impl Iterator for DriverIterator {
if self.index >= self.length {
None
} else {
unsafe {
let buf = sys::SDL_GetAudioDriver(self.index);
assert!(!buf.is_null());
self.index += 1;
let driver = get_audio_driver(self.index);
self.index += 1;

Some(CStr::from_ptr(buf as *const _).to_str().unwrap())
}
Some(driver)
}
}

Expand All @@ -375,10 +384,49 @@ impl Iterator for DriverIterator {
let remaining = (self.length - self.index) as usize;
(remaining, Some(remaining))
}

#[inline]
fn nth(&mut self, n: usize) -> Option<&'static str> {
use std::convert::TryInto;

self.index = match n.try_into().ok().and_then(|n| self.index.checked_add(n)) {
Some(index) if index < self.length => index,
_ => self.length,
};

self.next()
}
}

impl DoubleEndedIterator for DriverIterator {
#[inline]
fn next_back(&mut self) -> Option<&'static str> {
if self.index >= self.length {
None
} else {
self.length -= 1;

Some(get_audio_driver(self.length))
}
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<&'static str> {
use std::convert::TryInto;

self.length = match n.try_into().ok().and_then(|n| self.length.checked_sub(n)) {
Some(length) if length > self.index => length,
_ => self.index,
};

self.next_back()
}
}

impl ExactSizeIterator for DriverIterator {}

impl std::iter::FusedIterator for DriverIterator {}

/// Gets an iterator of all audio drivers compiled into the SDL2 library.
#[doc(alias = "SDL_GetAudioDriver")]
#[inline]
Expand Down
56 changes: 52 additions & 4 deletions src/sdl2/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2556,6 +2556,17 @@ pub struct DriverIterator {
index: i32,
}

// panics if SDL_GetRenderDriverInfo returns a nonzero value,
// which should only happen if index is outside the range
// 0..SDL_GetNumRenderDrivers()
fn get_render_driver_info(index: i32) -> RendererInfo {
let mut out = mem::MaybeUninit::uninit();
let result = unsafe { sys::SDL_GetRenderDriverInfo(index, out.as_mut_ptr()) };
assert_eq!(result, 0);

unsafe { RendererInfo::from_ll(&out.assume_init()) }
}

impl Iterator for DriverIterator {
type Item = RendererInfo;

Expand All @@ -2565,12 +2576,10 @@ impl Iterator for DriverIterator {
if self.index >= self.length {
None
} else {
let mut out = mem::MaybeUninit::uninit();
let result = unsafe { sys::SDL_GetRenderDriverInfo(self.index, out.as_mut_ptr()) == 0 };
assert!(result, "{}", 0);
let driver = get_render_driver_info(self.index);
self.index += 1;

unsafe { Some(RendererInfo::from_ll(&out.assume_init())) }
Some(driver)
}
}

Expand All @@ -2579,10 +2588,49 @@ impl Iterator for DriverIterator {
let remaining = (self.length - self.index) as usize;
(remaining, Some(remaining))
}

#[inline]
fn nth(&mut self, n: usize) -> Option<RendererInfo> {
use std::convert::TryInto;

self.index = match n.try_into().ok().and_then(|n| self.index.checked_add(n)) {
Some(index) if index < self.length => index,
_ => self.length,
};

self.next()
}
}

impl DoubleEndedIterator for DriverIterator {
#[inline]
fn next_back(&mut self) -> Option<RendererInfo> {
if self.index >= self.length {
None
} else {
self.length -= 1;

Some(get_render_driver_info(self.length))
}
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<RendererInfo> {
use std::convert::TryInto;

self.length = match n.try_into().ok().and_then(|n| self.length.checked_sub(n)) {
Some(length) if length > self.index => length,
_ => self.index,
};

self.next_back()
}
}

impl ExactSizeIterator for DriverIterator {}

impl std::iter::FusedIterator for DriverIterator {}

/// Gets an iterator of all render drivers compiled into the SDL2 library.
#[inline]
#[doc(alias = "SDL_GetNumRenderDrivers")]
Expand Down
64 changes: 56 additions & 8 deletions src/sdl2/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,20 @@ pub struct DriverIterator {
index: i32,
}

// panics if SDL_GetVideoDriver returns a null pointer,
// which only happens if index is outside the range
// 0..SDL_GetNumVideoDrivers()
fn get_video_driver(index: i32) -> &'static str {
use std::str;

unsafe {
let buf = sys::SDL_GetVideoDriver(index);
assert!(!buf.is_null());

str::from_utf8(CStr::from_ptr(buf as *const _).to_bytes()).unwrap()
}
}

impl Iterator for DriverIterator {
type Item = &'static str;

Expand All @@ -1998,15 +2012,10 @@ impl Iterator for DriverIterator {
if self.index >= self.length {
None
} else {
use std::str;

unsafe {
let buf = sys::SDL_GetVideoDriver(self.index);
assert!(!buf.is_null());
self.index += 1;
let driver = get_video_driver(self.index);
self.index += 1;

Some(str::from_utf8(CStr::from_ptr(buf as *const _).to_bytes()).unwrap())
}
Some(driver)
}
}

Expand All @@ -2015,10 +2024,49 @@ impl Iterator for DriverIterator {
let remaining = (self.length - self.index) as usize;
(remaining, Some(remaining))
}

#[inline]
fn nth(&mut self, n: usize) -> Option<&'static str> {
use std::convert::TryInto;

self.index = match n.try_into().ok().and_then(|n| self.index.checked_add(n)) {
Some(index) if index < self.length => index,
_ => self.length,
};

self.next()
}
}

impl DoubleEndedIterator for DriverIterator {
#[inline]
fn next_back(&mut self) -> Option<&'static str> {
if self.index >= self.length {
None
} else {
self.length -= 1;

Some(get_video_driver(self.length))
}
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<&'static str> {
use std::convert::TryInto;

self.length = match n.try_into().ok().and_then(|n| self.length.checked_sub(n)) {
Some(length) if length > self.index => length,
_ => self.index,
};

self.next_back()
}
}

impl ExactSizeIterator for DriverIterator {}

impl std::iter::FusedIterator for DriverIterator {}

/// Gets an iterator of all video drivers compiled into the SDL2 library.
#[inline]
#[doc(alias = "SDL_GetVideoDriver")]
Expand Down

0 comments on commit dfc982c

Please sign in to comment.