Browse Source

Fixed nits and such

pull/50/head
Andrea Ciliberti 3 years ago
parent
commit
6f15e54da9
  1. 1
      ctru-rs/Cargo.toml
  2. 10
      ctru-rs/src/gfx.rs
  3. 8
      ctru-rs/src/lib.rs
  4. 18
      ctru-rs/src/romfs.rs
  5. 18
      ctru-rs/src/services/apt.rs
  6. 22
      ctru-rs/src/services/fs.rs
  7. 14
      ctru-rs/src/services/hid.rs
  8. 46
      ctru-rs/src/services/mod.rs
  9. 18
      ctru-rs/src/services/soc.rs
  10. 22
      ctru-rs/src/services/sslc.rs
  11. 18
      ctru-rs/src/srv.rs

1
ctru-rs/Cargo.toml

@ -29,6 +29,7 @@ futures = "0.3"
time = "0.3.7" time = "0.3.7"
tokio = { version = "1.16", features = ["rt", "time", "sync", "macros"] } tokio = { version = "1.16", features = ["rt", "time", "sync", "macros"] }
cfg-if = "1.0.0" cfg-if = "1.0.0"
once_cell = "1.10.0"
[features] [features]
default = ["romfs"] default = ["romfs"]

10
ctru-rs/src/gfx.rs

@ -1,13 +1,13 @@
//! LCD screens manipulation helper //! LCD screens manipulation helper
use std::cell::RefCell; use std::cell::RefCell;
use std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Mutex; use std::sync::Mutex;
use crate::error::{Error, Result}; use crate::error::{Error, Result};
use crate::services::gspgpu::{self, FramebufferFormat}; use crate::services::gspgpu::{self, FramebufferFormat};
use crate::services::ServiceHandler; use crate::services::ServiceReference;
/// Trait implemented by TopScreen and BottomScreen for common methods /// Trait implemented by TopScreen and BottomScreen for common methods
pub trait Screen { pub trait Screen {
@ -73,10 +73,10 @@ pub enum Side {
pub struct Gfx { pub struct Gfx {
pub top_screen: RefCell<TopScreen>, pub top_screen: RefCell<TopScreen>,
pub bottom_screen: RefCell<BottomScreen>, pub bottom_screen: RefCell<BottomScreen>,
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static GFX_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); static GFX_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
impl Gfx { impl Gfx {
/// Initialize the Gfx module with the chosen framebuffer formats for the top and bottom /// Initialize the Gfx module with the chosen framebuffer formats for the top and bottom
@ -88,7 +88,7 @@ impl Gfx {
bottom_fb_fmt: FramebufferFormat, bottom_fb_fmt: FramebufferFormat,
use_vram_buffers: bool, use_vram_buffers: bool,
) -> Result<Self> { ) -> Result<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&GFX_ACTIVE, &GFX_ACTIVE,
false, false,
|| unsafe { || unsafe {

8
ctru-rs/src/lib.rs

@ -3,7 +3,6 @@
#![feature(test)] #![feature(test)]
#![feature(custom_test_frameworks)] #![feature(custom_test_frameworks)]
#![test_runner(test_runner::run)] #![test_runner(test_runner::run)]
#![feature(once_cell)]
extern "C" fn services_deinit() { extern "C" fn services_deinit() {
unsafe { unsafe {
@ -27,9 +26,13 @@ pub fn init() {
libc::atexit(services_deinit); libc::atexit(services_deinit);
} }
#[cfg(test)]
panic_hook_setup();
}
fn panic_hook_setup() {
use std::panic::PanicInfo; use std::panic::PanicInfo;
#[cfg(not(test))]
let main_thread = thread::current().id(); let main_thread = thread::current().id();
// Panic Hook setup // Panic Hook setup
@ -38,7 +41,6 @@ pub fn init() {
default_hook(info); default_hook(info);
// Only for panics in the main thread // Only for panics in the main thread
#[cfg(not(test))]
if main_thread == thread::current().id() && console::Console::exists() { if main_thread == thread::current().id() && console::Console::exists() {
println!("\nPress SELECT to exit the software"); println!("\nPress SELECT to exit the software");

18
ctru-rs/src/romfs.rs

@ -11,21 +11,21 @@
//! ``` //! ```
use std::ffi::CStr; use std::ffi::CStr;
use std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceHandler; use crate::services::ServiceReference;
#[non_exhaustive] #[non_exhaustive]
pub struct RomFS { pub struct RomFS {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static ROMFS_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); static ROMFS_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
impl RomFS { impl RomFS {
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&ROMFS_ACTIVE, &ROMFS_ACTIVE,
true, true,
|| { || {
@ -54,14 +54,14 @@ mod tests {
#[test] #[test]
fn romfs_duplicate() { fn romfs_duplicate() {
let _romfs = RomFS::init().unwrap(); let _romfs = RomFS::init().unwrap();
let lock = *ROMFS_ACTIVE.lock().unwrap(); let value = *ROMFS_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
drop(_romfs); drop(_romfs);
let lock = *ROMFS_ACTIVE.lock().unwrap(); let value = *ROMFS_ACTIVE.lock().unwrap();
assert_eq!(lock, 0); assert_eq!(value, 0);
} }
} }

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

@ -1,18 +1,18 @@
use std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceHandler; use crate::services::ServiceReference;
#[non_exhaustive] #[non_exhaustive]
pub struct Apt { pub struct Apt {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static APT_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); 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<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&APT_ACTIVE, &APT_ACTIVE,
true, true,
|| { || {
@ -23,11 +23,7 @@ impl Apt {
Ok(()) Ok(())
}, },
// `socExit` returns an error code. There is no documentantion of when errors could happen,
// but we wouldn't be able to handle them in the `Drop` implementation anyways.
// Surely nothing bad will happens :D
|| unsafe { || unsafe {
// The socket buffer is freed automatically by `socExit`
ctru_sys::aptExit(); ctru_sys::aptExit();
}, },
)?; )?;
@ -56,8 +52,8 @@ mod tests {
#[test] #[test]
fn apt_duplicate() { fn apt_duplicate() {
// We don't need to build a `Apt` because the test runner has one already // We don't need to build a `Apt` because the test runner has one already
let lock = *APT_ACTIVE.lock().unwrap(); let value = *APT_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
} }
} }

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

@ -9,7 +9,7 @@ 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 std::lazy::SyncLazy; 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;
@ -18,7 +18,7 @@ use std::sync::{Arc, Mutex};
use widestring::{WideCStr, WideCString}; use widestring::{WideCStr, WideCString};
use crate::services::ServiceHandler; use crate::services::ServiceReference;
bitflags! { bitflags! {
#[derive(Default)] #[derive(Default)]
@ -88,10 +88,10 @@ pub enum ArchiveID {
/// 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] #[non_exhaustive]
pub struct Fs { pub struct Fs {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static FS_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); static FS_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
/// Handle to an open filesystem archive. /// Handle to an open filesystem archive.
/// ///
@ -311,7 +311,7 @@ impl Fs {
/// 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<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&FS_ACTIVE, &FS_ACTIVE,
true, true,
|| { || {
@ -322,11 +322,7 @@ impl Fs {
Ok(()) Ok(())
}, },
// `socExit` returns an error code. There is no documentantion of when errors could happen,
// but we wouldn't be able to handle them in the `Drop` implementation anyways.
// Surely nothing bad will happens :D
|| unsafe { || unsafe {
// The socket buffer is freed automatically by `socExit`
ctru_sys::fsExit(); ctru_sys::fsExit();
}, },
)?; )?;
@ -1086,14 +1082,14 @@ mod tests {
fn fs_duplicate() { fn fs_duplicate() {
let _fs = Fs::init().unwrap(); let _fs = Fs::init().unwrap();
let lock = *FS_ACTIVE.lock().unwrap(); let value = *FS_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
drop(_fs); drop(_fs);
let lock = *FS_ACTIVE.lock().unwrap(); let value = *FS_ACTIVE.lock().unwrap();
assert_eq!(lock, 0); assert_eq!(value, 0);
} }
} }

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

@ -4,10 +4,10 @@
//! 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 std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceHandler; 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
@ -51,10 +51,10 @@ bitflags::bitflags! {
/// This service requires no special permissions to use. /// This service requires no special permissions to use.
#[non_exhaustive] #[non_exhaustive]
pub struct Hid { pub struct Hid {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static HID_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); 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] #[non_exhaustive]
@ -73,7 +73,7 @@ pub struct CirclePosition(ctru_sys::circlePosition);
/// rare in practice. /// rare in practice.
impl Hid { impl Hid {
pub fn init() -> crate::Result<Self> { pub fn init() -> crate::Result<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&HID_ACTIVE, &HID_ACTIVE,
true, true,
|| { || {
@ -176,8 +176,8 @@ mod tests {
#[test] #[test]
fn hid_duplicate() { fn hid_duplicate() {
// We don't need to build a `Hid` because the test runner has one already // We don't need to build a `Hid` because the test runner has one already
let lock = *HID_ACTIVE.lock().unwrap(); let value = *HID_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
} }
} }

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

@ -5,52 +5,10 @@ pub mod hid;
pub mod ps; pub mod ps;
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;
use crate::Error; pub (crate) use self::reference::ServiceReference;
use std::sync::Mutex;
pub(crate) struct ServiceHandler {
counter: &'static Mutex<usize>,
close: Box<dyn Fn()>,
}
impl ServiceHandler {
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 ServiceHandler {
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)();
}
}
}

18
ctru-rs/src/services/soc.rs

@ -1,18 +1,18 @@
use libc::memalign; use libc::memalign;
use std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceHandler; use crate::services::ServiceReference;
/// Soc service. Initializing this service will enable the use of network sockets and utilities /// Soc service. Initializing this service will enable the use of network sockets and utilities
/// such as those found in `std::net`. The service will be closed when this struct is is dropped. /// such as those found in `std::net`. The service will be closed when this struct is is dropped.
#[non_exhaustive] #[non_exhaustive]
pub struct Soc { pub struct Soc {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static SOC_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); static SOC_ACTIVE: Lazy<Mutex<usize>> = Lazy::new(|| Mutex::new(0));
impl Soc { impl Soc {
/// Initialize the Soc service with a default buffer size of 0x100000 bytes /// Initialize the Soc service with a default buffer size of 0x100000 bytes
@ -31,7 +31,7 @@ impl Soc {
/// ///
/// This function will return an error if the `Soc` service is already initialized /// This function will return an error if the `Soc` service is already initialized
pub fn init_with_buffer_size(num_bytes: usize) -> crate::Result<Self> { pub fn init_with_buffer_size(num_bytes: usize) -> crate::Result<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&SOC_ACTIVE, &SOC_ACTIVE,
true, true,
|| { || {
@ -69,14 +69,14 @@ mod tests {
#[test] #[test]
fn soc_duplicate() { fn soc_duplicate() {
let _soc = Soc::init().unwrap(); let _soc = Soc::init().unwrap();
let lock = *SOC_ACTIVE.lock().unwrap(); let value = *SOC_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
drop(_soc); drop(_soc);
let lock = *SOC_ACTIVE.lock().unwrap(); let value = *SOC_ACTIVE.lock().unwrap();
assert_eq!(lock, 0); assert_eq!(value, 0);
} }
} }

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

@ -1,21 +1,21 @@
// TODO: Implement remaining functions // TODO: Implement remaining functions
use std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceHandler; use crate::services::ServiceReference;
#[non_exhaustive] #[non_exhaustive]
pub struct SslC { pub struct SslC {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static SSLC_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); 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 = ServiceHandler::new( let _service_handler = ServiceReference::new(
&SSLC_ACTIVE, &SSLC_ACTIVE,
true, true,
|| { || {
@ -26,11 +26,7 @@ impl SslC {
Ok(()) Ok(())
}, },
// `socExit` returns an error code. There is no documentantion of when errors could happen,
// but we wouldn't be able to handle them in the `Drop` implementation anyways.
// Surely nothing bad will happens :D
|| unsafe { || unsafe {
// The socket buffer is freed automatically by `socExit`
ctru_sys::sslcExit(); ctru_sys::sslcExit();
}, },
)?; )?;
@ -57,14 +53,14 @@ mod tests {
fn sslc_duplicate() { fn sslc_duplicate() {
let _sslc = SslC::init().unwrap(); let _sslc = SslC::init().unwrap();
let lock = *SSLC_ACTIVE.lock().unwrap(); let value = *SSLC_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
drop(_sslc); drop(_sslc);
let lock = *SSLC_ACTIVE.lock().unwrap(); let value = *SSLC_ACTIVE.lock().unwrap();
assert_eq!(lock, 0); assert_eq!(value, 0);
} }
} }

18
ctru-rs/src/srv.rs

@ -1,18 +1,18 @@
use std::lazy::SyncLazy; use once_cell::sync::Lazy;
use std::sync::Mutex; use std::sync::Mutex;
use crate::services::ServiceHandler; use crate::services::ServiceReference;
#[non_exhaustive] #[non_exhaustive]
pub struct Srv { pub struct Srv {
_service_handler: ServiceHandler, _service_handler: ServiceReference,
} }
static SRV_ACTIVE: SyncLazy<Mutex<usize>> = SyncLazy::new(|| Mutex::new(0)); 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<Self> {
let _service_handler = ServiceHandler::new( let _service_handler = ServiceReference::new(
&SRV_ACTIVE, &SRV_ACTIVE,
true, true,
|| { || {
@ -40,14 +40,14 @@ mod tests {
fn srv_duplicate() { fn srv_duplicate() {
let _srv = Srv::init().unwrap(); let _srv = Srv::init().unwrap();
let lock = *SRV_ACTIVE.lock().unwrap(); let value = *SRV_ACTIVE.lock().unwrap();
assert_eq!(lock, 1); assert_eq!(value, 1);
drop(_srv); drop(_srv);
let lock = *SRV_ACTIVE.lock().unwrap(); let value = *SRV_ACTIVE.lock().unwrap();
assert_eq!(lock, 0); assert_eq!(value, 0);
} }
} }

Loading…
Cancel
Save