Browse Source

Reverted non-needing services and fixed issues

pull/50/head
Andrea Ciliberti 3 years ago
parent
commit
9d9dd8f90d
  1. 2
      ctru-rs/src/gfx.rs
  2. 2
      ctru-rs/src/lib.rs
  3. 2
      ctru-rs/src/romfs.rs
  4. 64
      ctru-rs/src/services/apt.rs
  5. 72
      ctru-rs/src/services/fs.rs
  6. 54
      ctru-rs/src/services/hid.rs
  7. 4
      ctru-rs/src/services/mod.rs
  8. 44
      ctru-rs/src/services/reference.rs
  9. 69
      ctru-rs/src/services/sslc.rs
  10. 59
      ctru-rs/src/srv.rs

2
ctru-rs/src/gfx.rs

@ -1,7 +1,7 @@
//! LCD screens manipulation helper //! LCD screens manipulation helper
use std::cell::RefCell;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::cell::RefCell;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Mutex; use std::sync::Mutex;

2
ctru-rs/src/lib.rs

@ -26,7 +26,7 @@ pub fn init() {
libc::atexit(services_deinit); libc::atexit(services_deinit);
} }
#[cfg(test)] #[cfg(not(test))]
panic_hook_setup(); panic_hook_setup();
} }

2
ctru-rs/src/romfs.rs

@ -10,8 +10,8 @@
//! romfs_dir = "romfs" //! romfs_dir = "romfs"
//! ``` //! ```
use std::ffi::CStr;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::ffi::CStr;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceReference; use crate::services::ServiceReference;

64
ctru-rs/src/services/apt.rs

@ -1,34 +1,15 @@
use once_cell::sync::Lazy; pub struct Apt(());
use std::sync::Mutex;
use crate::services::ServiceReference;
#[non_exhaustive]
pub struct Apt {
_service_handler: ServiceReference,
}
static APT_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
impl Apt { impl Apt {
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Apt> {
let _service_handler = ServiceReference::new( unsafe {
&APT_ACTIVE, let r = ctru_sys::aptInit();
true, if r < 0 {
|| { Err(r.into())
let r = unsafe { ctru_sys::aptInit() }; } else {
if r < 0 { Ok(Apt(()))
return Err(r.into()); }
} }
Ok(())
},
|| unsafe {
ctru_sys::aptExit();
},
)?;
Ok(Self { _service_handler })
} }
pub fn main_loop(&self) -> bool { pub fn main_loop(&self) -> bool {
@ -36,24 +17,19 @@ impl Apt {
} }
pub fn set_app_cpu_time_limit(&self, percent: u32) -> crate::Result<()> { pub fn set_app_cpu_time_limit(&self, percent: u32) -> crate::Result<()> {
let r = unsafe { ctru_sys::APT_SetAppCpuTimeLimit(percent) }; unsafe {
if r < 0 { let r = ctru_sys::APT_SetAppCpuTimeLimit(percent);
Err(r.into()) if r < 0 {
} else { Err(r.into())
Ok(()) } else {
Ok(())
}
} }
} }
} }
#[cfg(test)] impl Drop for Apt {
mod tests { fn drop(&mut self) {
use super::*; unsafe { ctru_sys::aptExit() };
#[test]
fn apt_duplicate() {
// We don't need to build a `Apt` because the test runner has one already
let value = *APT_ACTIVE.lock().unwrap();
assert_eq!(value, 1);
} }
} }

72
ctru-rs/src/services/fs.rs

@ -9,17 +9,13 @@ use std::io::Error as IoError;
use std::io::ErrorKind as IoErrorKind; use std::io::ErrorKind as IoErrorKind;
use std::io::Result as IoResult; use std::io::Result as IoResult;
use std::io::{Read, Seek, SeekFrom, Write}; use std::io::{Read, Seek, SeekFrom, Write};
use once_cell::sync::Lazy;
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::ptr; use std::ptr;
use std::slice; use std::slice;
use std::sync::{Arc, Mutex}; use std::sync::Arc;
use widestring::{WideCStr, WideCString}; use widestring::{WideCStr, WideCString};
use crate::services::ServiceReference;
bitflags! { bitflags! {
#[derive(Default)] #[derive(Default)]
struct FsOpen: u32 { struct FsOpen: u32 {
@ -86,12 +82,7 @@ pub enum ArchiveID {
/// until an instance of this struct is created. /// until an instance of this struct is created.
/// ///
/// The service exits when all instances of this struct go out of scope. /// The service exits when all instances of this struct go out of scope.
#[non_exhaustive] pub struct Fs(());
pub struct Fs {
_service_handler: ServiceReference,
}
static FS_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
/// Handle to an open filesystem archive. /// Handle to an open filesystem archive.
/// ///
@ -105,7 +96,6 @@ static FS_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
/// let fs = Fs::init().unwrap(); /// let fs = Fs::init().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap(); /// let sdmc_archive = fs.sdmc().unwrap();
/// ``` /// ```
#[non_exhaustive]
pub struct Archive { pub struct Archive {
id: ArchiveID, id: ArchiveID,
handle: u64, handle: u64,
@ -174,7 +164,6 @@ pub struct Archive {
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[non_exhaustive]
pub struct File { pub struct File {
handle: u32, handle: u32,
offset: u64, offset: u64,
@ -186,7 +175,6 @@ pub struct File {
/// represents known metadata about a file. /// represents known metadata about a file.
/// ///
/// [`metadata`]: fn.metadata.html /// [`metadata`]: fn.metadata.html
#[non_exhaustive]
pub struct Metadata { pub struct Metadata {
attributes: u32, attributes: u32,
size: u64, size: u64,
@ -269,7 +257,6 @@ pub struct OpenOptions {
/// ///
/// This Result will return Err if there's some sort of intermittent IO error /// This Result will return Err if there's some sort of intermittent IO error
/// during iteration. /// during iteration.
#[non_exhaustive]
pub struct ReadDir<'a> { pub struct ReadDir<'a> {
handle: Dir, handle: Dir,
root: Arc<PathBuf>, root: Arc<PathBuf>,
@ -310,24 +297,15 @@ impl Fs {
/// ctrulib services are reference counted, so this function may be called /// ctrulib services are reference counted, so this function may be called
/// as many times as desired and the service will not exit until all /// as many times as desired and the service will not exit until all
/// instances of Fs drop out of scope. /// instances of Fs drop out of scope.
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Fs> {
let _service_handler = ServiceReference::new( unsafe {
&FS_ACTIVE, let r = ctru_sys::fsInit();
true, if r < 0 {
|| { Err(r.into())
let r = unsafe { ctru_sys::fsInit() }; } else {
if r < 0 { Ok(Fs(()))
return Err(r.into()); }
} }
Ok(())
},
|| unsafe {
ctru_sys::fsExit();
},
)?;
Ok(Self { _service_handler })
} }
/// Returns a handle to the SDMC (memory card) Archive. /// Returns a handle to the SDMC (memory card) Archive.
@ -1007,6 +985,14 @@ impl Seek for File {
} }
} }
impl Drop for Fs {
fn drop(&mut self) {
unsafe {
ctru_sys::fsExit();
}
}
}
impl Drop for Archive { impl Drop for Archive {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
@ -1073,23 +1059,3 @@ impl From<ArchiveID> for ctru_sys::FS_ArchiveID {
} }
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fs_duplicate() {
let _fs = Fs::init().unwrap();
let value = *FS_ACTIVE.lock().unwrap();
assert_eq!(value, 1);
drop(_fs);
let value = *FS_ACTIVE.lock().unwrap();
assert_eq!(value, 0);
}
}

54
ctru-rs/src/services/hid.rs

@ -4,11 +4,6 @@
//! and circle pad information. It also provides information from the sound volume slider, //! and circle pad information. It also provides information from the sound volume slider,
//! the accelerometer, and the gyroscope. //! the accelerometer, and the gyroscope.
use once_cell::sync::Lazy;
use std::sync::Mutex;
use crate::services::ServiceReference;
bitflags::bitflags! { bitflags::bitflags! {
/// A set of flags corresponding to the button and directional pad /// A set of flags corresponding to the button and directional pad
/// inputs on the 3DS /// inputs on the 3DS
@ -49,19 +44,12 @@ bitflags::bitflags! {
/// when all instances of this struct fall out of scope. /// when all instances of this struct fall out of scope.
/// ///
/// This service requires no special permissions to use. /// This service requires no special permissions to use.
#[non_exhaustive] pub struct Hid(());
pub struct Hid {
_service_handler: ServiceReference,
}
static HID_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
/// Represents user input to the touchscreen. /// Represents user input to the touchscreen.
#[non_exhaustive]
pub struct TouchPosition(ctru_sys::touchPosition); pub struct TouchPosition(ctru_sys::touchPosition);
/// Represents the current position of the 3DS circle pad. /// Represents the current position of the 3DS circle pad.
#[non_exhaustive]
pub struct CirclePosition(ctru_sys::circlePosition); pub struct CirclePosition(ctru_sys::circlePosition);
/// Initializes the HID service. /// Initializes the HID service.
@ -72,24 +60,15 @@ pub struct CirclePosition(ctru_sys::circlePosition);
/// Since this service requires no special or elevated permissions, errors are /// Since this service requires no special or elevated permissions, errors are
/// rare in practice. /// rare in practice.
impl Hid { impl Hid {
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Hid> {
let _service_handler = ServiceReference::new( unsafe {
&HID_ACTIVE, let r = ctru_sys::hidInit();
true, if r < 0 {
|| { Err(r.into())
let r = unsafe { ctru_sys::hidInit() }; } else {
if r < 0 { Ok(Hid(()))
return Err(r.into()); }
} }
Ok(())
},
|| unsafe {
ctru_sys::hidExit();
},
)?;
Ok(Self { _service_handler })
} }
/// Scans the HID service for all user input occurring on the current /// Scans the HID service for all user input occurring on the current
@ -169,15 +148,8 @@ impl CirclePosition {
} }
} }
#[cfg(test)] impl Drop for Hid {
mod tests { fn drop(&mut self) {
use super::*; unsafe { ctru_sys::hidExit() };
#[test]
fn hid_duplicate() {
// We don't need to build a `Hid` because the test runner has one already
let value = *HID_ACTIVE.lock().unwrap();
assert_eq!(value, 1);
} }
} }

4
ctru-rs/src/services/mod.rs

@ -3,12 +3,12 @@ pub mod fs;
pub mod gspgpu; pub mod gspgpu;
pub mod hid; pub mod hid;
pub mod ps; pub mod ps;
mod reference;
pub mod soc; pub mod soc;
pub mod sslc; pub mod sslc;
mod reference;
pub use self::apt::Apt; pub use self::apt::Apt;
pub use self::hid::Hid; pub use self::hid::Hid;
pub use self::sslc::SslC; pub use self::sslc::SslC;
pub (crate) use self::reference::ServiceReference; pub(crate) use self::reference::ServiceReference;

44
ctru-rs/src/services/reference.rs

@ -0,0 +1,44 @@
use crate::Error;
use std::sync::Mutex;
pub(crate) struct ServiceReference {
counter: &'static Mutex<usize>,
close: Box<dyn Fn()>,
}
impl ServiceReference {
pub fn new<S, E>(
counter: &'static Mutex<usize>,
allow_multiple: bool,
start: S,
close: E,
) -> crate::Result<Self>
where
S: FnOnce() -> crate::Result<()>,
E: Fn() + 'static,
{
let mut value = counter.lock().unwrap(); // todo: handle poisoning
if *value == 0 {
start()?;
} else if !allow_multiple {
return Err(Error::ServiceAlreadyActive);
}
*value += 1;
Ok(Self {
counter,
close: Box::new(close),
})
}
}
impl Drop for ServiceReference {
fn drop(&mut self) {
let mut value = self.counter.lock().unwrap(); // should probably handle poisoning - could just map_err to ignore it.
*value -= 1;
if *value == 0 {
(self.close)();
}
}
}

69
ctru-rs/src/services/sslc.rs

@ -1,66 +1,35 @@
// TODO: Implement remaining functions // TODO: Implement remaining functions
use once_cell::sync::Lazy; pub struct SslC(());
use std::sync::Mutex;
use crate::services::ServiceReference;
#[non_exhaustive]
pub struct SslC {
_service_handler: ServiceReference,
}
static SSLC_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
impl SslC { impl SslC {
/// Initialize sslc /// Initialize sslc
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Self> {
let _service_handler = ServiceReference::new( unsafe {
&SSLC_ACTIVE, let r = ctru_sys::sslcInit(0);
true, if r < 0 {
|| { Err(r.into())
let r = unsafe { ctru_sys::sslcInit(0) }; } else {
if r < 0 { Ok(SslC(()))
return Err(r.into()); }
} }
Ok(())
},
|| unsafe {
ctru_sys::sslcExit();
},
)?;
Ok(Self { _service_handler })
} }
/// Fill `buf` with `buf.len()` random bytes /// Fill `buf` with `buf.len()` random bytes
pub fn generate_random_data(&self, buf: &mut [u8]) -> crate::Result<()> { pub fn generate_random_data(&self, buf: &mut [u8]) -> crate::Result<()> {
let r = unsafe { ctru_sys::sslcGenerateRandomData(buf.as_ptr() as _, buf.len() as u32) }; unsafe {
if r < 0 { let r = ctru_sys::sslcGenerateRandomData(buf.as_ptr() as _, buf.len() as u32);
Err(r.into()) if r < 0 {
} else { Err(r.into())
Ok(()) } else {
Ok(())
}
} }
} }
} }
#[cfg(test)] impl Drop for SslC {
mod tests { fn drop(&mut self) {
use super::*; unsafe { ctru_sys::sslcExit() };
#[test]
fn sslc_duplicate() {
let _sslc = SslC::init().unwrap();
let value = *SSLC_ACTIVE.lock().unwrap();
assert_eq!(value, 1);
drop(_sslc);
let value = *SSLC_ACTIVE.lock().unwrap();
assert_eq!(value, 0);
} }
} }

59
ctru-rs/src/srv.rs

@ -1,53 +1,20 @@
use once_cell::sync::Lazy; pub struct Srv(());
use std::sync::Mutex;
use crate::services::ServiceReference;
#[non_exhaustive]
pub struct Srv {
_service_handler: ServiceReference,
}
static SRV_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
impl Srv { impl Srv {
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Srv> {
let _service_handler = ServiceReference::new( unsafe {
&SRV_ACTIVE, let r = ctru_sys::srvInit();
true, if r < 0 {
|| { Err(r.into())
let r = unsafe { ctru_sys::srvInit() }; } else {
if r < 0 { Ok(Srv(()))
return Err(r.into()); }
} }
Ok(())
},
|| unsafe {
ctru_sys::srvExit();
},
)?;
Ok(Self { _service_handler })
} }
} }
#[cfg(test)] impl Drop for Srv {
mod tests { fn drop(&mut self) {
use super::*; unsafe { ctru_sys::srvExit() };
#[test]
fn srv_duplicate() {
let _srv = Srv::init().unwrap();
let value = *SRV_ACTIVE.lock().unwrap();
assert_eq!(value, 1);
drop(_srv);
let value = *SRV_ACTIVE.lock().unwrap();
assert_eq!(value, 0);
} }
} }

Loading…
Cancel
Save